面試被問到了var和let的區(qū)別划址,對于我這個前端老菜鳥來說扔嵌,本來是個送分題昏滴,結(jié)果給搞成了送命題,畢竟面試造火箭对人,工作擰螺絲谣殊,現(xiàn)在拿起課本重新復習一下吧:
1.使用var聲明的變量,其作用域為該語句所在的函數(shù)內(nèi)牺弄,且存在變量提升現(xiàn)象姻几;
2.使用let聲明的變量,其作用域為該語句所在的代碼塊內(nèi)势告,不存在變量提升蛇捌;
先說以下什么是變量提升和函數(shù)提升吧:
(1)、變量提升:
ES6出現(xiàn)之前咱台,ES5只有全局作用域和函數(shù)作用域的概念络拌,并沒有塊級作用域這個概念,變量提升即:變量聲明提升到它所在作用域的最開始的部分回溺,比如以下的例子:
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();
為什么會出現(xiàn)以上情況呢春贸?js 代碼的執(zhí)行分為兩個階段:第一個階段在當前詞法環(huán)境中注冊所有的變量和函數(shù)聲明,簡單說就是遗遵,解析萍恕;第二個階段的 js 執(zhí)行就開始了!
也就是是按照以下過程開始解析的:
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)车要、函數(shù)提升
js中創(chuàng)建函數(shù)有兩種方式:函數(shù)聲明式和函數(shù)字面量式允粤,只有函數(shù)聲明才存在函數(shù)提升!翼岁!如:
func(); // 1
var func;
function func() {
console.log(1);
}
func = function() {
console.log(2);
}
函數(shù)聲明和變量聲明都會被提升类垫,在定義的函數(shù)名字和變量名相同的情況下:函數(shù)提升的優(yōu)先級大于變量提升的優(yōu)先級,即函數(shù)提升在變量提升之上琅坡。
等同于這樣:
function func() {
console.log(1);
}
func(); // 1
func = function() {
console.log(2);
}
最后再來說以下var和let的區(qū)別:
ES6新出的命令let悉患,與var類似,但是脑蠕,
(1)所聲明的變量只在let命令所在的代碼塊內(nèi)有效购撼;
(2)let 不存在變量提升而且有暫時性死區(qū)的約束;
(3)let變量不能重復聲明
var a = 99; // 全局變量a
f(); // f是函數(shù)谴仙,雖然定義在調(diào)用的后面迂求,但是函數(shù)聲明會提升到作用域的頂部。
console.log(a); // a=>99, 此時是全局變量的a
function f() {
console.log(a); // 當前的a變量是下面變量a聲明提升后晃跺,默認值undefined
var a = 10;
console.log(a); // a => 10
}
f(); // f是函數(shù)揩局,雖然定義在調(diào)用的后面,但是函數(shù)聲明會提升到作用域的頂部掀虎。
function f() {
console.log(a); // let 不存在變量提升凌盯,所以會報錯
let a = 10;
console.log(a); // a => 10
}