let和const(call和phototype)
使用let和const声明的变量,不能再被重新声明
let的声明不会污染全局变量,var声明的都是全局变量,let作用于块级作用域,使用完会被释放掉,用var声明的变量存在变量提升,而用let声明的变量不存在变量提升
变量提升
在浏览器进行解析的时候,一般把var a = “hello”先全局寻找变量,把变量var a 提升,赋值undefined,然后执行到该函数的时候再将hello赋值给a
暂存死区
首先来看一段代码
let name = "CIA" { console.log(name) let name = "CIA again" } console.log(name)
讲道理这段代码第一个输出语句,位于块级作用域中,向上拿不到变量值CIA,向下也拿不到CIA again,因为不存在变量提升,但是第二个输出语句按道理应该可以输出CIA,因为程序的执行是从上到下的,但是程序一条输出语句都没有执行,因为有暂存死区这个概念,当执行到第一条输出语句的时候,就已经报错了,程序中中断不在继续向下执行了。
//var var i = 0; for(i =1;i<=10;i++){ (function(i){ var btn = document.createElement("button") btn.innerHTML = i; btn.addEventListener("click",function(){ alert(i) }) document.body.appendChild(btn) })(i) } //let for(let i =1;i<=10;i++){ var btn = document.createElement("button") btn.innerHTML = i; btn.addEventListener("click",function(){ alert(i) }) document.body.appendChild(btn) }
const
不能重复声明,不存在提升,只在当前块级作用域内有效,在声明的时候就必须被初始化。
const只能保证声明的常量所指向的地址不变,不能保证地址上的值不能发生改变,比如修改对象的属性值,修改数组的值.
那么怎么防止常量为引用类型的时候能被修改的情况,使用object。freeze()方法
// Object.freeze() const xiaoming = { age: 14, name: '小明' }; Object.freeze(xiaoming); console.log(xiaoming); xiaoming.age = 22; xiaoming.dd = 11; console.log(xiaoming); //同样适用于数组
es6之前怎么声明常量
var CST = {a: 1}; Object.defineProperty(CST, 'a', { writable: false //a是只读的,不能被修改 }); Object.seal(CST);
抽象通用方法
// 1. 遍历属性和方法 // 2. 修改遍历到的属性的描述 // 3. Object.seal() Object.defineProperty(Object, 'freezePolyfill', { //在object对象上挂一个方法 value: function(obj) { var i; for (i in obj) { if (obj.hasOwnProperty(i)) {//避免拿到原型上的属性 Object.defineProperty(obj, i, { writable: false }); } } Object.seal(obj); } }); const xiaoming = { age: 14, name: '小明', obj: { a: 1 } }; Object.freezePolyfill(xiaoming);
Repetition is the mother of all learning重复是学习之母。等到长大,学知识,技巧、爱情、事业、交流....倘若懂得行动的力量,不怕重复,不怕犯错误,那就大有希望靠近幸福了。