1.变量声明let和const
在ES6以前,var关键字声明变量。无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。这就是函数变量提升例如:
function aa() { if(bool) { var test = 'hello man' } else { console.log(test) } }
以上代码实际为:
var bool=true; function aa() { var test // 变量提升 if(bool) { test = 'hello man'; console.log(test) } else { //此处访问test 值为undefined console.log(test) } console.log(test)//此处访问test 值为'hello man } console.log(test)//错误 aa();
ES6中:
const:常量;
let:变量;
const PI2= 3.1415926 PI2 = 201452789 //再次赋值此时会报错 //常量则不能更改
const callbacks=[]; for(var i=0;i<=2;i++){ callbacks[i]=function(){ return i*2; } } console.table([ callbacks[0](), callbacks[1](), callbacks[2](), ])
运行结果“
const callbacks2=[]; //只有let这一处不一样!!!! for(let i=0;i<=2;i++){ callbacks2[i]=function(){ return i*2; } } console.table([ callbacks2[0](), callbacks2[1](), callbacks2[2](), ])
代码结果:
因为let和const都是块级作用域。let的作用域是在它所在当前代码块,但不会被提升到当前函数的最顶部。
const再次声明对象的引用时,不会报错!
const b={ a:3 }; b.a=4; b.c=5; console.log(b.a); //4 console.log(b.c); //5
const b={ a:3 }; b=2; //Uncaught SyntaxError: Identifier 'b' has already been declared
因为对象是引用类型,返回的是对象存储的指针,上例中,b是指向存储的指针,指针因为const是不变的,但是它指向的内容b.a可以变。
2.ES5中块作用域:立即执行函数: ( (function(){}) ());
( (function(){ function f2(){ return 1; } console.log(f2()===1); //true }) () ); ( (function(){ function f2(){ return 2; } console.log(f2()===2); //true }) () )
ES6中块作用域:{}
{ function f2(){ return 1; } console.log(f2()===1); //true } { function f2(){ return 2; } console.log(f2()===2); //true }
3.箭头函数
ES5 function a(){}
{ const evens=[1,3,5,7]; const odds=evens.map( function(v){ return v+1; }) console.log(evens,odds); //(4) [1, 3, 5, 7] (4) [2, 4, 6, 8] }
ES6 ()=>{} //只有一个参数时,小括号可以省略;{}中的表达式直接作为返回值时,{}也可以省略
{ const evens=[1,3,5,7]; const odds=evens.map(v=>v+1); console.log(evens,odds); //(4) [1, 3, 5, 7] (4) [2, 4, 6, 8] }
ES6中this没有形成自己的作用域,this指向离它最近的作用域块
//ES5 function Foo(){ this.a='a'; this.b='b'; //此处为构造函数,则this 指向实例f2本身 this.c={ a:'a+', b:function(){ return this.a; //此处thi.c为都对象,则this指向对象本身 } } } var f2=new Foo(); console.log(f2.c.b()); //a+
//ES6 function Foo(){ this.a='a'; this.b='b'; this.c={ a:'a+', b:()=>this.a } } var f2=new Foo(); console.log(f2.c.b()); //a
4.默认参数
//ES5 function f(x,y,z){ y=y||2; z=z||2; return x+y+z}; f(2)//6; f(2,3)//7 f(2,3,4)//9
//ES6 function f(x,y=2,z=2){return x+y+z}; f(2)//6; f(2,3)//7 f(2,3,4)//9
f() //NaN
5.异常参数检测
在4的实例中,函数f调用时应至少传入一个参数,那若一个参数都不传入时,会显示NaN; ES6可以用在此处作参数异常检测;
{ function cheackPara(){ throw new Error('There isn\'t a parameter'); } function f(x= cheackPara(),y=2,z=2){ return x+y+z}; try{ f() } catch(e){ console.log(e) } //Error: There isn't a parameter }
可变参数
//ES5 需要借助数组的arguments { function f(){ var a=Array.prototype.slice.call(arguments); var sum=0; a.forEach(function(item){ sum+=item; }) return sum; } console.log(f(1)); //1 console.log(f(1,2,3)); //6 }
//ES6 function f(...a){ //... 为扩展运算符,则a为可变参数列表 var sum=0; a.forEach(item=>{sum+=item}); return sum; } console.log(f(1)); //1 console.log(f(1,2,3)); //6
//ES5合并数组 var a=[1,2,3]; var b=[4,5]; b=b.concat(a) //[4,5, 1, 2, 3] console.log(b); c=[4,5].concat(a); console.log(c); //[4,5, 1, 2, 3]
//ES6运用扩展运算符合并数组 var a=[1,2,3]; var b=[4,5]; b=[b,...a]; //[Array(2), 1, 2, 3] console.log(b); c=[4,5,...a]; console.log(c); //[4,5, 1, 2, 3]
6.ES6代理
ES6中数据保护,原理就是通过访问代理,对数据访问做限制,最终提供的数据不是源数据
{ let Person={ name:'ES6', sex:'male', age:16 }; let person= new Proxy( Person,{ //代理 get (target,key){ //读操作 return target[key]; }, set (target,key,value){ //写操作 if(key !=='sex'){ target[key]=value; } } }); console.table({ name: person.name, //此处的person为代理,不是原数据 sex: person.sex, age: person.age }) }
运行结果:
更多ES6相关知识