let const 出现的作用
ES6规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为
作用域
es6之前
- 全局作用域
- 函数作用域
- eval作用域
es6 块级作用域
对花括号{}之间的区域
//special 注意这里的花括号代表的是一个对象不是块级作用域
var obj={
a:1
}
复制代码
块级作用域可以嵌套
let & var
var
- 存在变量提升
let
只在当前块级作用域有效
{
var a=1;
let b=2
}
console.log(a);//1
console.log(b);//err 只在块级作用域中有效
for(let i=0;i<3;i++){
console.log(i);//0 1 2
};
console.log(i); //undefined
for(var i=0;i<3;i++){
console.log(i);//0 1 2
};
console.log(i);// 3 使用var没有被释放
复制代码
声明的变量不能重复声明
let b="b";
let b="a" //err
复制代码
不存在变量提升
console.log(b);
let b="1"; //err
复制代码
暂存死区(Temporal Dead Zone)
let b=1;
{
console.log(b);
let b=2;
}
console.log(b);//err let形成封闭作用域 又不存在变量提示 拿不到值
复制代码
与通过 var 声明的有初始化值 undefined 的变量不同,通过 let 声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致 ReferenceError。该变量处在一个自块顶部到初始化处理的“暂存死区”中。
const常量
常量声明后不可以被修改
const a="codehua"
a="frank" //err
复制代码
常量为引用类型时,可以被修改,防止被修改的方法
引用类型:对象、数组、函数
复制代码
const codeHua={
age:22,
name:'frank'
};
console.log(codeHua);
codeHua.age=23;
console.log(codeHua);//age=23
codeHua={ };//err
复制代码
原因:const 是保证我们声明的常量所指向的地址不变(仿佛记起学C的时候的指针),不能保证地址上的值发生改变。
当 codeHua={}的时候指向了新地址,则不能被修改,而codeHua.age=23只是修改地址上的值。
//防止常量被修改
const codeHua={
age:22,
name:'frank'
};
Object.freeze(codeHua);//使用Object.freeze()方法
console.log(codeHua);
codeHua.age=23;
console.log(codeHua);
复制代码
Object.freeze()
冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
es6之前怎么声明常量polifill
//模拟常量
var CST={};
Object.defineProperty(CST,'BASE_NAME',{
value:'codeHua',
writable:false
});//先在对象上定义一个新属性
Object.seal(CST);//封闭一个对象阻止添加新的属性值
//该简单polyfill有个缺点如果添加的属性未对象则可以修改值,应再加判断递归思路 这里先不填坑了
复制代码
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
Object.seal()
封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。密封的对象可以改变它们现有的属性。使用Object.freeze() 冻结的对象中现有属性是不可变的。
Polyfill
是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。