var
var 聲明的變量是函數(shù)作用域變量碳想。
var a = 1;
var a = 2;
等價于
var a宋渔;
var a;
a = 1;
a = 2;
var 聲明的變量提到作用域的前方,簡稱變量提升督暂。
看一個例子
var a = 1;
function foo(){
alert(a);
var a = 2;
}
foo.call()
alert(a)打出來的是什么揪垄?
我們先做一下轉(zhuǎn)換,先找聲明逻翁,把聲明提升到作用域的前方饥努,再看代碼。
var a;
function foo(){
var a;
alert(a);
a = 2;
}
a = 1;
foo.call()
轉(zhuǎn)換后的代碼八回,我們就一目了然了酷愧,alert(a)打出來undefined
function f1(){
if(true){
}else{
var a = 1
}
alert(a)
}
f1();
跟前面一樣,先找聲明缠诅,把聲明提升到作用域的前方溶浴,再看代碼。
function f1(){
var a;
if(true){
}else{
a = 1
}
alert(a)
}
f1();
此時的alert(a)也是undefined管引。
for(var i = 0;i < 6;i++){
setTimeout(function(){
console.log(i)
},1000)
}
打印出i的值是什么呢士败?
先把聲明提升上去,再看代碼汉匙,1s之后for循環(huán)早已執(zhí)行完畢拱烁,此時i的值為6,再執(zhí)行函數(shù)噩翠,結(jié)果console.log(i)就是6個6戏自。
let
let 聲明的變量是塊級作用域變量。
let 無法重復(fù)聲明
let 和 for 循環(huán)一起使用有奇怪現(xiàn)象
let 聲明的變量提升到塊級作用域的第一行
實際聲明的一行與塊級作用域第一行之間的區(qū)域伤锚,就是該let 變量的TDZ(臨時死亡區(qū)域)
let a = 1;
let a = 2;
//Uncaught SyntaxError: Identifier 'a' has already been declared
重復(fù)聲明會報錯
for(let i = 0;i < 6;i++){
setTimeout(function(){
console.log(i)
}擅笔,1000)
}
打印出i的值是什么?打印出0 1 2 3 4 5,結(jié)果跟我們想的一樣猛们,但過程卻不一樣念脯。
變量i是let聲明的,當(dāng)前的i只在本輪循環(huán)有效弯淘,所以每一次循環(huán)的i其實都是一個新的變量
let a = 1;
{
console.log(a);
let a = 2;
}
console.log(a)會打出什么呢绿店?
先做轉(zhuǎn)換,再代碼庐橙。
let a;
a = 1;
{
let a;
console.log(a);
a = 2;
}
轉(zhuǎn)換完假勿,感覺console.log(a)是undefined.再看看let的第五大特性,console.log(a)這行代碼就是TDZ(臨時死亡區(qū)域)态鳖,所以執(zhí)行的結(jié)果會報錯转培。
先let聲明變量,再使用浆竭。