let const var
参考资料:https://es6.ruanyifeng.com/#docs/let
1. var示例代码【结合之后特点对应查看】:
/* 1. 变量声明提升举例 */ console.log(age); age = 16; console.log(age); var age = 18;
/* 2. 不存在块级作用域举例 */ var arr = []; for (var i = 0; i < 5; i++) { arr[i] = function () { console.log(i); } } arr[2](); // 会发现结果并非想象中的2,而是5 var arr = []; for (var i = 0; i < 5; i++) { (function (i) { arr[i] = function () { console.log(i); } })(i) } arr[2](); // 匿名立即执行函数可以解决此问题,但过于繁琐,ES6 let更方便
/* 3. 可重复声明变量 */ var age = 15; var age = 19; // 不报错 console.log(age);
var: 1. 存在变量声明提升:当一个变量用var声明时,js会将其提升到所有js代码顶部,
可以在变量声明语句之前使用此变量,
不会报错,只是值为undefined.
console.log(age); // undefined
age = 16;
console.log(age); // 16
var age = 18;
实际上js会解析为:
var age;
console.log(age);
age = 16;
console.log(age);
age = 18;
2. 没有块级作用域概念
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[2](); // 会发现结果并非想象中的2,而是5
这是因为var在非函数作用域中声明的变量为全局变量,不存在块级作用域概念,因此
所有的console.log(i)中的i都是指向全局变量,当所有循环执行完,i已经变成5,所以最终结果为5
var arr = [];
for (var i = 0; i < 5; i++) {
(function (i) {
arr[i] = function () {
console.log(i);
}
})(i)
}
arr[2](); // 匿名立即执行函数可以解决此问题,但过于繁琐,ES6 let更方便
3. 在同一作用域可以重复声明同名变量
var age = 15;
var age = 19; // 不报错
console.log(age); // 19
2. let示例代码【结合之后特点对应查看】:
/* 1. 存在块级作用域 */ let arr = []; for (let i = 0; i < 5; i++) { arr[i] = function () { console.log(i); } } arr[2](); // 2
/* 2. 暂时性死区 */ let tmp = 'tdz'; if (true) { console.log(tmp); // Uncaught ReferenceError: Cannot access 'tmp' before initialization let tmp = 15; }
let: 1. 不存在变量提升,必须先声明后使用
2. 存在块级作用域
let arr = [];
for (let i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[2](); // 2
同时需要注意:for小括号()和{}不是同一个块级作用域
设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
} // 这段代码正常运行,如果它们是同一块作用域,那么因为let中不可以重复声明变量,理论上会报错.
3. 不可以重复声明变量
4. 存在暂时性死区:即一个变量被使用let声明后,它就和所在的块级作用域绑定了,如果在此区域内,
在let声明语句之前使用此变量,会直接报错,哪怕外部作用域已经有同名变量
let tmp = 'tdz';
if (true) {
// Uncaught ReferenceError: Cannot access 'tmp' before initialization
console.log(tmp);
let tmp = 15;
}
3. const:
const: 1. 必须声明时初始化
2. 初始化后内存地址不可修改,这意味着如果是值,那么这个值无法改变,如果是对象或数组,
那么对象或数组里面的内容是可以改变的.
如果希望里面内容也不可修改,那么使用const obj = Object.freeze({});来初始化一个空对象,
这个对象无法添加任何属性

浙公网安备 33010602011771号