- 作用域相關題目一
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() {
return i;
})
console.log(funcs[i]())
}
funcs.forEach(function(func) {
console.log(func());
})複製程式碼
這道題的輸出結果
解析:funcs陣列Push進去了十個匿名函式,在for迴圈的作用域內直接呼叫可以輸出i的值,在for迴圈結束後,全域性變數i 的值為10,此時forEach函式遍歷呼叫裡面的匿名函式,沿著作用域向上尋找到 i =10,所以列印十個10
這題還涉及到一個關鍵的知識:函式只有在呼叫的時候才會執行內部的方法,否則只是定義了一個方法
如何讓forEach正確輸出0-9,有兩種方法
方法1:ES5的立即執行函式
立即執行函式會建立一個獨立的作用域,相當於“私有”的名稱空間
var funcs = []
for(var i = 0; i < 10; i++) {
funcs.push(
(function(value) {
return function() {
return value;
}
})(i)
)
}
funcs.forEach(function(func) {
console.log(func())
})
複製程式碼
方法2:ES6的let
var funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
return i;
})
console.log(funcs[i]())
}
funcs.forEach(function(func) {
console.log(func());
})複製程式碼
2.題目二
console.log(a) // undefined
var a = 100
console.log(a) // 100
function person(name){ // 宣告函式
age=20
console.log(name,age)
var age
}
person('man') // double,20複製程式碼
瀏覽器解析時,把變數進行提升,然後全設定為undefined,等到執行到賦值時才進行賦值
3.題目二
var i = 10
function aaa () {
i = 20
console.log(i) // 第1個log 20
for (var i = 0; i < 6; i++) {
console.log(i) // 第2個log 0 1 2 3 4 5
}
console.log(this.i) // 第3個log 10
console.log(i) // 第4個log 6
}
aaa()
console.log(i) // 第5個log 10複製程式碼
這題涉及到四個點
- 內部環境可以通過作用域鏈訪問所有的外部環境
- 外部環境不能訪問內部環境中的任何變數
- 即每個環境都可以向上搜尋作用域鏈,以查詢變數和函式
- 任何環境不能向下搜尋作用域鏈而進入另一環境
上面程式碼等價於下
var i = 10
function aaa () {
var i //變數提升
i = 20
console.log(i) // 第1個log 20
for (i = 0; i < 6; i++) {
console.log(i) // 第2個log 0 1 2 3 4 5
}
console.log(this.i) // 第3個log 10
console.log(i) // 第4個log 6
}
aaa()
console.log(i) // 第5個log 10複製程式碼
第一個輸出 由於給區域性變數i賦值 所以輸出20
第二個輸出for迴圈 輸出0 1 2 3 4 5,當i = 6時終止迴圈
第三個輸出,在一般函式中使用this指代全域性物件,此是this.i = window.i 輸出10
第四個輸出,上面for迴圈結束後i =6 ,所以輸出6
第五個輸出,輸出全域性變數 i =10