ES6之let与const
ECMAScript与JavaScript的关系: ES是JS的标准,JS是ES的实现。 European Computer Manufactures Association欧洲计算机制造联合会。 浏览器对新标准的支持情况:http://kangax.github.io/compat-table/es6/
关于let
使用var声明或不声明直接使用变量时,本质上是往window对象上添加了属性。
let与var的主要区别:
1,let声明的变量旨在当前(块级)作用域{}(对象的{}不算)内有效。
2,let声明和const声明的变量不能被重复声明。
3,不存在变量提升,不会把声明提前。
4,如果块级作用域中存在let或者const声明的变量,这个变量一开始就会形成一个封闭的作用域,形成暂存死区。
在for中使用let时,for后面的括号内算是一个作用域,括号后面的{}算是括号作用域的子作用域。类似作用域的嵌套,第一层是括号内的,第二层是花括号内的{ { } }。
暂存死区:
let b = 14;
{
console.log(b);//报错。不会沿着作用域链查找,因为该作用域有了let声明的变量b,把该针对b变量,把该作用域封闭了,然后let又不会变量提升,提前声明,所以不存在b,所以报错。
let b =5;
}
{ let a = 1; { let b = 2; console.log(a);//1 } console.log(b);//报错 }
看不懂的话就自己动手试试!(自己对自己说的)
//js实现一个1-10的按钮点击弹出对应数字 //闭包 for (var i = 1; i < 11; i++) { (function (i) { var btn = document.createElement('button'); btn.innerText = i; btn.onclick = function() { alert(i); } document.body.appendChild(btn); })(i); } //let for (let i = 1; i < 11; i++) { var btn = document.createElement('button'); btn.innerText = i; btn.onclick = function() { alert(i); } document.body.appendChild(btn); }
关于const
常量-不可改变的量。
常量必须在声明的时候赋值。否则报错。
与let类似的特性:
不能重复声明,不存在变量提升,只在当前块级作用域内有效。
与let的区别:
常量一旦声明就不可改变,但常量如果为引用类型的时候,不能保证不可变。
实质上,const只能保证常量的地址不变,不能保证地址上的内容发生改变。
怎么防止常量为引用类型的时候能被修改的情况:
Object.freeze(引用类型常量);
ES6之前怎么声明常量:
1,var xx = xx;//假装是常量。
2,Obejct.defineProperty(对象名,'属性名',{ value: '小明', writable: false });//往对象上添加属性,可添加描述,如能不能枚举,修改,配置。
Object.seal(对象名);//防止对象被扩展,但是可以修改原有属性。
两个结合。完成常量的效果。
使用for-in遍历对象的时候,会将原型上的方法也遍历一边,所以需要obj.hasOwnProperty(属性);//返回true的时候就是自身拥有的属性,而不是原型上拥有的属性。
以下代码自己封装了一个Object.freeze2()方法。
Object.defineProperty(Object, 'freeze2', {//定义属性 value: function(obj) { for ( var p in obj ) { if (obj.hasOwnProperty(p)) { Object.defineProperty(obj, p, { writable: false//不可修改属性 }); if ( typeof obj[p] === 'object' ) { Object.freeze2(obj[p]); } } } Object.seal(obj);//防止对象属性的扩展 } }); var obj = { age: 55, obj2: { xx: 22, obj3: { ff: 233 } } } Object.freeze2(obj);