文章目录
ES5语法
严格模式
-
必须用var生命变量
-
禁止用自定义函数中的this指向window对象
-
创建eval作用域
var str = 'NBA';
eval('alert(str)')
//能解析里面的字符串并执行
//但eval里的变量自动会提升到全局
//所以用严格模式,将eval创建了作用域,变成私有
- 对象不能有重名的属性
Json对象
json.stringfy(obj/arr)
//将对象或数组转化为json对象
json.parse(json)
//同理
- json是一种传输数据的格式
- 可以很轻松的拿到对象的属性
object包
-
object.create(prototype ,[descriptors]) obj ={username : 'jjr', age:'1'} var obj1={} obj1 =object.create(obj, { sex:{ value:'boy'//实际指定值 writeable:true//可不可以修改,默认为faluse configurable:true//是否可以被删除,默认为faluse-- delete obj1.sex enumerable:true//标识属性是否能用for in来枚举 默认为false //for(var i in obj1){ //console.log(i)会没有sex属性 //} } } )
-
object.defineproperties(obj,description) //用来扩展属性 var obj ={username : 'jjr', age:'1'} object.defineproperties(obj, { fullname:{ get:function(){ return this.username + " " +this.age; } //这就是获取属性的值 set:function(data){ //监听扩展属性,当扩展属性回调的时候自动调用,将变化的值作为实参进行注入 }
-
get propertyname(){} //用来得到当前属性值的回调函数 set propertyname(){} //用来监视当前属性值改变的回调函数
array数组的扩展
indexOf(value)拿value出现第一次出现的下标
lastindexof()拿value出现最后一次出现的下标
foreach((item , index)=>{})遍历数组
map((item , index)=>{})能返回一个新的数组(比遍历多能操作)
filter((item , index)=>{})能返回一个新的数组
函数的扩展
绑定obj用call和apply
var obj={username : 'jjr', age:'1'}
function foo(data){
consolo.log(this,data)
}
foo.call(obj)可以绑定
foo.apply(obj)
不传参的情况下是一样的
foo.call(obj,33)
//直接从第二个参数开始,依次传入
foo.apply(obj,[33])
//第二个必须是数组传入要放在数组里
foo.blind(obj)
blind()是将函数返回,不会立即调用当前的函数
所以有 var bar = foo.blind(obj)
再有bar(data)
可以合并
foo.blind(obj ,33)()
回调函数:不是立即调用的,所以要用blind
ES6语法
const and let
- 在块级作用域内有效
- 不能重复申明
- 不会预处理,不存在块级提升
- 在for循环中用let
- 使用let取代var是趋势
点击是回调函数,在实践队列里面,在主队列里完成后再勾出执行//用闭包可以避免
- 不能修改
- 其它特点同let
- 保存不用改变的数据
- 如果是对象的话,属性的值是可以改变,但是属性的名字和数量是不能改变的
变量的解构赋值
-
从对象或数组中提取数据,并赋值给变量(多个)
-
对象的解构赋值
let {n,a}={n:'tom',a:12} //必须是已有的属性 let {n:newa,a}={n:'tom',a:12} //改名 可以直接拿数据 let {n}={n:'tom',a:12}//n:'tom' let {a}={n:'tom',a:12}//a:12
-
数组的解构赋值
let [a,b]=['tom',12] //不可以直接拿数据 //要预留空出来 let [,,,a,b]=[1,2,3,4,5]//a=4,b=5 let [,,a,b]=[1,2,3,4,5]//a=3,b=4 let [,,...a]=[1,2,3,4,5]//a=[3,4,5] //省略号必须是最后一个
-
用途:给多个形参赋值
-
var obj={username : 'jjr', age:'1'} function foo({username,age}){ consol.log(username,age) } foo{obj}
模板字符串
- 简化字符串的拼接
- 模板字符串必须用``包含
- 变化的部分必须用$(XXX)定义
let obj={username:'kobe',age:39}
let str = '我的名字叫'+obj.usename+',我今年的年龄是'+obj.age
let str1 = `我的名字叫$(obj.usename),我今年的年龄是$(obj.age)`
简化的对象obj内的写法
-
省略同名的属性值
-
省略方法的function
-
let x=1; let y=2; let point ={ x, y, setX(x){this.x=x} } let point1 = { x:x, y:y,//原本的写法 //所以同名的属性可以不写 getx:function(){ //可以省略:function return this.name; } //可以变成如下模式 getx(){ return this.name; } }
箭头函数
-
作用:定义匿名函数
-
没有参数:()=>console.log(‘xxx’)
-
一个参数的情况i=>i+2
-
大于一个参数(i,j)=>i+j
-
函数体不用大括号的时候默认返回结果
-
如果函数有多个语句(即有大括号的时候){},若有需要返回的内容,需要手动返回
-
使用场景多用来定义回调函数
-
特点
-
简洁
-
箭头函数没有自己的this,箭头函数的this不是在调用的是由决定的,而是在定义的时候所处对象就是它的this
-
常规函数的this就是谁调用它就用谁
-
扩展理解: 箭头函数的this看外层是否有函数 如果有,外层函数的this就是内部箭头函数的this 如果没有,则this是window
-
let fun = function (){
console.log('arrow')
}
let fun1 = () =>console.log('arrow');
fun1()
let fun2 = a =>console.log('a');
fun2('aaa')
let fun3 = (a,b) =>console.log(a,b);
fun3(25 ,26)
let fun3 = (a,b) =>{
console.log(a,b);
return a+b;
}
let fun4 = (a,b) =>a+b;
let sum = fun4(25 ,26)
//没有return的话,返回值会默认为undefined
三点运算符
-
也叫…运算符
-
reset可变参数,形参的位置
三点运算符进行收集只能放在最后(in function)
function fun(a,...values){ console.log(arguments); //arguments.forEach(function //(item,index){ //console.log(item,index) //})可见arguments是伪运算符 //还有callee的自我回调方法 console.log(values); values.forEach(function (item,index){ console.log(item,index) }) //真数组可以用数组的方法 } fun(1,2,3)
-
扩展运算符,实参
相当于将数组遍历并且拿到每一项值
let arr1 = [1,3,5] let arr2 = [2 ,...arr1,6] arr.push(...arr1)
形参默认值
当不传入参数的时候默认使用形参里的默认值
function point(x = 1,y = 2){
this.x=x;
this.y=y
}
let point = new point(23,35);//x=23,y=35
let point1 = new point(35);//x=35,y=2
let point1 = new point();//x=1,y=2
promise对象
symbol
-
原有的数据类型(string, number, Boolean ,null, undefined ,对象)
-
symbol是一种新添加的数据类型
-
symbol属性对应的值是唯一的,解决命名冲突的问题
-
symbol值不能与其他数据进行计算,包括同字符串拼接
-
for in 和for of 遍历时不会遍历symbol属性
-
使用
-
调用symbol函数得到symbol值
创建symbol属性值 let symbol = Symbol(); 不需要new console.log(symbol)//symbol()
-
传参标识
let symbol1 = Symbol('one') let symbol2 = Symbol('two') console.log(symbol1,symbol2) //Symbol(one) Symbol(two)
-
Symbol 类型还可以用于定义一组常量,保证这组常量的值都是不相等的。
-
内置symbol值
除了定义自己使用的Symbol值意外,es6还提供了11个内置的Symbol值,指向语言内部的使用方法
-
Symbol.iterator
对象的Symbol.iterator属性,指向带对象的默认遍历器方法(后面讲)
-
let obj ={username :'kobe' ,age:39}
obj[symbol] = 'hello'
console.log(obj)
//Symbol():'hello'
const mySymbol = Symbol();
const a = {};
a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
//上面代码中,因为点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个 Symbol 值。
//实际上JavaScript对象的所有属性都是字符串,不过属性对应的值可以是任意数据类型。
//同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
let s = Symbol();
let obj = {
[s]: function (arg) { ... }
};
obj[s](123);
Iterator遍历器
- iterator(迭代器的意思)是一种接口机制,为各种不同的数据结构提供统一 的访问机制
- 作用
- 为各种数据结构提供一个统一的,简便的访问接口
- 使得数据结构的成员能够按某种次序排列
- es6创造了一种新的遍历命令for of循环,iterator接口主要是攻for of使用
- 工作原理
- 创建一个指针对象(遍历器对象),指向数据结构的其实位置
- 第一次调用next方法,指针自动指向数据结构的第一个成员
- 接下来每调用next方法,指针会一直往后一定,知道指向最后一个成员
- 每台哦用next方法的时候返回的是一个包含value和done的对象
- value:当前成员的值
- done: 布尔值
- value标识当前成员的值,东阿对应的布尔值标识当前的数据结构是否遍历结束
- 当遍历结束的时候返回的value是undefined,done值为false
- 原生具备iterator接口的数据(可以用for of 来进行遍历)
- 扩展理解
- 当数据结构上部署了symbol.iterator的接口的时候,该数据就可以用for of 遍历
- 当使用for of 遍历目标数据结构发的时候,该数据会自动去找symbol.iterator属性
- symbol.iterator属性指向对象的默认遍历器方法
- array
- arguments
- set容器
- map容器
function myIterator(arr){
let nextIndex=0
return {
//遍历器对象
next:function(){
return {
nextIndex <arr.length ? {value:arr[nextIndex++],done:false} : {value:undefined done:true}
}
}
}
}
//准备一个数据
let arr = [1,4 7,'abc']
let iteratorObj=myIterator(arr);
iteratorObj.next();
iteratorObj.next()
以上会被es6提前加到数据类型上
将iterator接口部署到指定的数据类型,就可以使用for of循环遍历
已经有的(数组,字符串,arguments,set和map容器)
let arr = [1,4 7,'abc']
for(let i of arr){
console.log(i)
}
let str = 'abcde'
for(let i of str){
console.log(i)
}
function fun(){
for(let i of arguments){
console.log(i)
}
//arguments是一个伪数组,没有数组的一般方法,所以没有for each方法
}
fun(1,4,5,'abc')
而对象上没有部署iterator,所以不能用for of 方法来进行遍历
使用三点运算符和解构赋值的时候默认覅你用iterator接口
let arr2=[1,6]
let arr3=[1,...arr2,6]
//即遍历arr2的值
同理解构赋值
闭包
-
概念
闭包函数:声明在一个函数中的函数,叫做闭包函数。 -
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
-
特点
-
让外部访问函数内部变量成为可能;
-
局部变量会常驻在内存中;
-
可以避免使用全局变量,防止全局变量污染;
-
会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
-
闭包的创建:
闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。闭包会发生内存泄漏,每次外部函数执行的时 候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删除,保留一根指针给内部活动对象。
————————————————
版权声明:本文为优快云博主「羊二哥」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_43586120/article/details/89456183
Symbol.Interator
等同于在指定的数据结构上部署了iterator接口
当使用for of去遍历一个数据结构的时候,首先去找Symbol.Interator,找到了就去遍历,没有的话就不能遍历(obj is not iterator)
let targetData={
[Symbol.Interator]:function(){
let nextIndex=0
return {
//遍历器对象
next:function(){
return {
nextIndex <this.length ? {value:this[nextIndex++],done:false} : {value:undefined done:true}
}
}
}
}
}
Generator函数
-
es6解决一部变成的方案之一
-
generator函数是一个状态机,内部封装了不同状态的数据
-
用来生成遍历器对象
-
可暂停函数(惰性求值),yield可暂停,next方法可启动,每次返回的是yield后的表达式结果
-
特点
-
function与函数名之间有一个型号
-
内部用yield表达式来定义不同的状态
-
function * generatorExample(){ let result = yield 'hello'//状态值为hello //result值为undefined,即yield返回正常会为undefined //但有next(值)会传回去 yield 'generator'//状态值为generator }
-
generator函数执行返回的是指针对象(遍历器对象)(是iterator),而不会执行函数内部的逻辑
-
调用generator函数执行的返回值的next方法时,函数内部的逻辑才开始执行,遇到yield表达式停止,返回{value:yield后的表达式/语句的执行结果的返回值/undefined,done:false/true(遍历完毕)}
-
再次调用next方法会从上一次停止的yield处开始,直到最后
-
function * myGenerator(){
console.log('开始执行')
yield 'hello'//状态hello
console.log('暂停后,继续执行')
yield 'generator'//状态generator
}
let MG = myGenerator()
//返回一个指针对象
//MG.next()
console.loge(MG.next())
//{value:hello,done:false}
let obj={uername:'jjr',age:'18'}
obj[Symbol.interator]=function*mygenerator(){
yield 1;
yield 2;
yield 3;
}
for(let i of obj){
console.log(i)
}
//1 2 3
function getNews(url){
$.get(url,function(data){
console.log(data//得到的数据)
let url=''+data.数据
SX.next(url)
})//jquery method import
}
function * sendXml(){
let url=yield getNews(网址)
yield getNews(url)
}
let SX = sendXml();
SX.next();
async函数(ES7)
-
真正意义上的去解决异步回调的问题,同步流程来表达一部的操作
-
本质:genenrator的语法糖(让generator方法更加完善)
-
语法
async function foo(){ await //异步操作 //等异步操作执行完成后,执行下一个 await //异步操作 }
-
特点
- 不需要像generator函数去调用next方法,遇到await等待,当前的一部操作完成就往下执行
- 返回的总是promise对象,可以用then方法进行下一步操作
- async取代的时Generator函数的星号,await取代的俄式Generator的yield
- 语义上更加明确,使用简单,没有任何副作用和不良反应
async function foo(){
return new Promise(resolve=>{
setTimeout(function(){
resolve()
},2000)
setTimeout(resolve,2000)
})
}
async function test(){
console.log('begin',new Date().toTimeString)
await foo()
//无需next,会自动执行
console.log('end',new Date().toTimeString)
}
-
await的返回值
function teat2() { return 'xxx' } async function asyncPrint(){ let result = await teat2() console.log(result) } asyncPrint() //"xxx"
async function asyncPrint(){ let result = await Promise.resolve('promise'); console.log(result) result = await Promise.reject('fail') console.log(result) } asyncPrint() //promise // Uncaught (in promise) fail
class
- 通过class定义类,实现类的继承(js之前用原型继承)
- 再类中通过constructor()定义构造方法
- 通过new创建类的实列
- 通过extends实现类的继承
- 通过super()调用父类的构造方法
- 重写父类中继承的一般方法
class Person {
constructor(name,age){
this.name=name;
this.age=age
}
//类的一般方法
showName(){
console.log(this.name)
}
//放在实列对象的原型上,不是对象的本身上
}
let person = new Preson('kobe',39)
class starPerson extends Person(){
constructor(name,age,salary){
super(name,age)
//标识调用父类的构造方法
//this.name=name;
//this.age=age
//跟java一样
this.salary = salary
}
showName(){
console.log(this.name,this.age,this.salary)
}
//方法的覆盖/父类的方法的重写
}
- 再类中通过constructor()定义构造方法
- 通过new创建类的实列
- 通过extends实现类的继承
- 通过super()调用父类的构造方法
- 重写父类中继承的一般方法
class Person {
constructor(name,age){
this.name=name;
this.age=age
}
//类的一般方法
showName(){
console.log(this.name)
}
//放在实列对象的原型上,不是对象的本身上
}
let person = new Preson('kobe',39)
class starPerson extends Person(){
constructor(name,age,salary){
super(name,age)
//标识调用父类的构造方法
//this.name=name;
//this.age=age
//跟java一样
this.salary = salary
}
showName(){
console.log(this.name,this.age,this.salary)
}
//方法的覆盖/父类的方法的重写
}