let吱型、const定義的變量為什么通過window獲取不到
先看幾個case:
let count = 10
console.log(count)
console.log(window.count)
輸出:10 undefined
const length = 5
const obj = {
length: 6,
foo(bar) {
bar()
arguments[0]()
}
}
function bar() {
console.log(this.length)
}
obj.foo(bar, 2, 4)
輸出: 0 3
var length = 5
const obj = {
length: 3,
foo(bar) {
bar()
arguments[0]()
}
}
function bar() {
console.log(this.length)
}
obj.foo(bar, 3)
輸出: 5 2
為什么赤屋?ES5 和 ES6變量聲明方式的區(qū)別導致的。首先總結下ES5 和 ES6 的變量聲明方式师逸。
- ES5 變量聲明方式就兩種 var司倚、function
- ES6 有 let、const篓像、import动知、class,再加上ES5 的var 和 function 總共6種
- DOM 的頂層對象是document员辩,BOM的頂層對象是window盒粮,Node的全局對象是global
- ES5中頂層對象的屬性等價于全局變量
- 在ES6中,用let奠滑、const丹皱、import、class定義的全局變量并沒有作為全局對象的屬性宋税,所以通過window獲取時种呐,如果window存在和變量同名的屬性,則獲取的是window中該屬性的原始值弃甥,否則為undefined
- 用let const在聲明的時候,是創(chuàng)建了一個遮蔽window同名屬性的全局變量汁讼,debuger一下就可以看出來用 let const 定義的變量作用域為Script對象中淆攻,和Window/Global同級。
如圖:
所以
- case1首先打印10嘿架,其次是window中不存在的count屬性瓶珊,undefined
- case2 調(diào)用bar時,this指向window耸彪,而window中的length屬性為0伞芹,所以輸出0。通過arguments[0]調(diào)用蝉娜,函數(shù)內(nèi)的this指向argument唱较,arguments為類數(shù)組,其length屬性為實參的個數(shù)召川,即 3
- case3 使用var聲明length南缓,會修改window中的length屬性(window的length 屬性的原始值是當前窗口中frames的數(shù)量(包括IFRAMES)),所以值為0
暫時性死區(qū)(TDZ)
let const聲明的變量會放在TDZ中荧呐,TDZ指的是從變量的當前的作用域開始到變量的聲明之間的區(qū)域汉形,這一段區(qū)域的變量是無法讀寫的纸镊。只有在執(zhí)行了聲明之后,才從TDZ移除概疆。
注意點:
變量提升控制的是當前作用域或者執(zhí)行環(huán)境逗威,因此某個TDZ也只負責某個執(zhí)行環(huán)境。
console.log(typeof value) // undefined
{
console.log(typeof value) // 報錯 value is not defined
const value = 'rose'
}
可以看出if外訪問 value 不會報錯岔冀,因為 if 外 typeof value時變量還沒有在TDZ中凯旭,所以是undefined。