语句使用
ES5 中不能直接声明一个常量,如果想声明一个不可修改的变量需要借助 defineProperty 方法;
ES6 为了弥补这方面的缺失,新增了 const 语句用于声明一个常量;
基本使用
-
const 的使用类似于 let,不同的是 const 在声明时必须初始化一个值,而且这个值不能被改变;
const PI = 3.1415; // 定义一个圆周率常量 PI const PI; // Uncaught SyntaxError: Missing initializer in const declaration const PI = 3.1415; // 定义一个圆周率常量 PI PI = 12; // Uncaught TypeError: Assignment to constant variable.
-
如果使用 const 声明的变量是一个对象类型的话,可以改变对象里的值,这是因为 const 存的变量只是一个地址的引用,只要不改变引用的值,就不会报错;
const obj = {}; obj.a = 12 // 12 const arr = []; arr.push(12); // 12 arr = {}; // Uncaught TypeError: Assignment to constant variable.
const 和 let 共有特性
-
不能进行变量提升,在声明前不能被使用,否则会抛出异常;
-
存在暂时性死区,在块中不能被重复声明;
ES5 模拟实现 const
在 ES6 之前是不能定义常量的,如果想定义常量的话,需要借助 ES5 中的 defineProperty 方法;
function setConst(key, value) {
// 在 window 对象上添加属性,也可以自己定义一个对象进行添加,可以实现局部作用域的效果
Object.defineProperty(window, key, {
get: function(){
return value;
},
set: function(){
console.error('Uncaught TypeError: Assignment to constant variable');
},
});
}
setConst('PI', 3.1415);
console.log(PI) // 3.1415
PI = 3; // Uncaught TypeError: Assignment to constant variable.
场景实例
什么是变量提升?
变量还没有被声明,但却可以使用这个未被声明的变量,这种情况就叫做提升,并且提升的是声明;
不仅变量可以被提升,函数也可以被提升,并且函数的提升要优于变量的提升,函数提升会把整个函数挪到作用域顶部;
什么是暂时性死区?
暂时性死区主要是针对 let 和 const 而言的,因为它们不存在变量提升,所以在它们声明变量之前是不能使用的,这个时候如果使用了就会报错,这时候就形成了暂时性的死区,也就是不能被引用;
定义前被引用则会抛出异常;
面试题
下面的代码输出的结果是什么?
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 1000*i);
}
// var 声明的变量是全局作用域的,循环完后 i 的值是 3
// 3
// 3
// 3
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 1000 * i);
}
// 这里循环的变量 i 是 let 声明的,当前的 i 只在本轮循环有效,所以每一次循环的 i 其实都是一个新的变量
// for 循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域
// 0
// 1
// 2
// 闭包
for (var i = 0; i < 3; i++) {
(function (i) {
setTimeout(() => {
console.log(i);
}, 1000 * i);
})(i)
}
ES6+ let
上一篇