今天来总结一下es6里面let与const的用法
先总体看一下es6中的let都有哪些特性:
let 特性
1. 同名变量不可以重复声明2. let声明的变量不存在变量提升的问题
1 var a = 100;
2 et b = 20; // 报错
2. let声明的变量不存在变量提升的问题
1 /** 2 * es6新出的变量定义方式声明的变量不再与全局对象相关联 3 * 即class , let , const , import 声明的变量不会把变量挂到全局对象上 4 **/ 5 let num = 10; 6 console.log(window.num); //undefined 7 var num2 = 10; 8 console.log(window.num2); //10
我们都知道,js在全局中声明变量,其实质是哪个就是将该变量挂载到window对象的属性上,因此,在访问全局变量时,与访问window对象的属性是一致的。js的设计者逐渐意识到设计存在问题,因此,逐渐开始全局对象与全局变量进行分离。在使用let或者const,甚至之后的class声明变量,都不再将全局变量挂载全局对象(window或者global上)
3. 在es6中还引入了块级作用域的概念。
使用let和const声明的变量只在申明语句所在的块级作用域有效。离开了块级作用域,变量的声明失效,因此也不存在变量的提升。
1 { 2 var a = 100; 3 let b = 200; 4 } 5 6 console.log(a); // 100 7 console.log(b); // b is not defined
使用let和const+块级作用域的声明方式可以在某种程度上代替立即执行函数的方式
1 let vari = 123; 2 // 立即执行函数解决变量命名冲突问题 3 (function(){ 4 let vari = 456; 5 console.log(vari); // 4561 6 }()) 7 8 // 块级作用域解决变量重名问题 9 { 10 let vari = 789 11 console.log(vari); // 789 12 } 13 console.log(vari); // 123
很显然,利用es6的块级作用域解决命名冲突更加简洁明了。
4.暂时性死区。
1 let a = 10; 2 { 3 // 使用let声明变量时,变量会存放在暂时性死区中,在执行声明语句之前不可以使用该变量 4 // 即使全局中有a变量也不行 5 console.log(a); // a is not defined 6 let a = 5; 7 }
以上的代码在其他编程语言中是不会报错的,但是在js中就会报错。虽然在全局声明了变量a,但在块级作用域中,存在let的声明语句,变量将会被存放在暂时性死区中。存放在暂时性死区中的变量,只有在执行了变量的声明语句之后才会从暂时性死区中取出使用。
5.函数声明方式
1 { 2 /** 3 * 1. 在块级作用域内允许声明函数 4 * 2. 函数声明类似于var声明,将变量声明提升到函数作用域或者全局作用域前面,但函数体不提升 5 * 3. 函数声明提升到所在块级作用域的头部 6 **/ 7 function f() { console.log('i am in outside!'); } 8 (function () { 9 // f(); //f is not a function ,说明函数的声明提升到了函数作用域的头部,在此处已有f变量的声明,其值为undefined 10 // console.log(f); 11 if (true) { 12 // f = 10; 13 console.log(f); //此处f的值为函数体,说明函数整体提升到了块级作用域的头部 14 // f = 10; 15 function f() { console.log('i am in inside!'); } 16 } 17 }()); 18 }
在块级作用域中允许申明函数,不过该声明方式与es5的形式不同,在es6的块级作用域中声明函数,会将函数的声明部分提升到块级作用域的头部,而函数提不提升。
关于const的用法,其声明特性与let一致,只不过const声明的一般类型变量值是不可以修改的,对于引用数据类型来说是可以修改的。const声明的实质是const声明的对象的栈内存空间不能再改变,而引用变量所指向的堆内存空间是可以改变的。
1 { 2 let obj = { 3 name: 'zhang', 4 age: 18, 5 birthday: { 6 year: 2018, 7 month: 13, 8 day: 32 9 } 10 }; 11 let myfreeze = (obj) => { 12 for (let prop in obj) { 13 // object.freeze()方法能够是对象属性的值不可改,相当于加上了const声明 14 object.freeze(obj); 15 // 若对象的属性依旧是引用类型,则递归处理 16 if (typeof (obj[prop]) === 'object') { 17 // console.log('referencing prop'); 18 myfreeze(obj[prop]); 19 } 20 } 21 return obj; 22 } 23 var constobj = myfreeze(obj); 24 console.log(obj); 25 obj.birthday.year = 1998; //此处修改属性无效
用上面的递归方式即可将一个对象转换为对象常量,即对象中所有的属性,不可更改。
let与const的出现使得js的变量生命更加规范,因此,建议使用const和let的方式声明变量。
如对本文有疑问, 点击进行留言回复!!
offset、client、scroll (width,height、left,top、X,Y)
网友评论