面试被问到了var和let的区别,对于我这个前端老菜鸟来说,本来是个送分题,结果给搞成了送命题,毕竟面试造火箭,工作拧螺丝,现在拿起课本重新复习一下吧:
1.使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
2.使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
先说以下什么是变量提升和函数提升吧:
(1)、变量提升:
ES6出现之前,ES5只有全局作用域和函数作用域的概念,并没有块级作用域这个概念,变量提升即:变量声明提升到它所在作用域的最开始的部分,比如以下的例子:
console.log(a); //undefined
var a = 1;
console.log(a); // 1
function fn(){
console.log(b); //undefined
var b = 2;
console.log(b); //2
}
fn();
为什么会出现以上情况呢?js 代码的执行分为两个阶段:第一个阶段在当前词法环境中注册所有的变量和函数声明,简单说就是,解析;第二个阶段的 js 执行就开始了!
也就是是按照以下过程开始解析的:
var a;
console.log(a); // undefined =>因为声明了变量但是并没有初始化
a= 1;
console.log(a); //1 => 因为给a初始化了值
function fn(){
console.log(b); //undefined =>因为声明了变量但是并没有初始化
var b = 2;
console.log(b); //2 => 因为给b初始化了值
}
fn();
(2)、函数提升
js中创建函数有两种方式:函数声明式和函数字面量式,只有函数声明才存在函数提升!!如:
func(); // 1
var func;
function func() {
console.log(1);
}
func = function() {
console.log(2);
}
函数声明和变量声明都会被提升,在定义的函数名字和变量名相同的情况下:函数提升的优先级大于变量提升的优先级,即函数提升在变量提升之上。
等同于这样:
function func() {
console.log(1);
}
func(); // 1
func = function() {
console.log(2);
}
最后再来说以下var和let的区别:
ES6新出的命令let,与var类似,但是,
(1)所声明的变量只在let命令所在的代码块内有效;
(2)let 不存在变量提升而且有暂时性死区的约束;
(3)let变量不能重复声明
var a = 99; // 全局变量a
f(); // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。
console.log(a); // a=>99, 此时是全局变量的a
function f() {
console.log(a); // 当前的a变量是下面变量a声明提升后,默认值undefined
var a = 10;
console.log(a); // a => 10
}
f(); // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。
function f() {
console.log(a); // let 不存在变量提升,所以会报错
let a = 10;
console.log(a); // a => 10
}