最近面试的时候就把let和var详细的比较,让填写输出结果,才意识到一直以为的掌握了,实际上还是掌握的皮毛,现在就把这部分好好总结一下,分享一下吧~共同进步!
-
通过var定义的变量,作用域是整个封闭函数,是全域的 。通过let定义的变量,作用域是在块级或是子块中
for (let i = 0; i < 3; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
for (var i = 0; i < 3; i++) {
// ...
}
console.log(i);
// 3
let作用于在块级或是子块中
var作用域是整个封闭函数
-
变量提升
浏览器在运行代码之前会进行预解析,首先解析函数声明,定义变量,解析完之后再对函数、变量进行运行、赋值等。 不论var声明的变量处于当前作用域的第几行,都会提升到作用域的头部并初始化为undefined,而let声明的变量在作用域的顶部未被初始化,在代码块内,使用let命令声明变量之前,该变量都是不可用的,尽管代码块外也存在相同全局变量。
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
//相当于
var foo; //声明且初始化为undefined
console.log(foo);
foo=2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
//相当于在第一行先声明bar但没有初始化,直到赋值时才初始化
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
alert(tmp); //输出值为123,全局tmp与局部tmp不影响
-
重复声明
let不允许在相同作用域内重复声明同一个变量。
使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误,.如果重复使用的一个声明没有一个初始值,那么它不会对原来存在的变量有任何的影响.
// var 的情况
var a = 100;
console.log(a); //100
var a;
console.log(a); //100
var a = 300;
console.log(a); //300
// let 的情况
let a = 100;
console.log(a); //100
let a = 300;
console.log(a); //Identifier 'a' has already been declared
-
let声明变量,值可以改变。const声明常量,值不可改变(使用const时,常量最好使用大写),其他的属性let与const一致。
let a = 10;
a = 20;
console.log(a); //20
const B = 30;
B = 40; //Uncaught TypeError: Assignment to constant variable.
console.log(B);
const只保证常量名指向的地址不变,并不能保证地址的数据不变,如果想吧对象冻结数据不可改变,可使用Object.freeze(obj)
const a = {};
a.name = 'gary';
console.log(a.name); //gary
const b = Object.freeze({});
b.name = 'bob';
console.log(b.name); //undefined
网友评论