JS-作用域題目

徐海東發表於2019-02-20
  1. 作用域相關題目一
    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());
    })複製程式碼

這道題的輸出結果JS-作用域題目


解析: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複製程式碼

這題涉及到四個點

  1. 內部環境可以通過作用域鏈訪問所有的外部環境
  2. 外部環境不能訪問內部環境中的任何變數
  3. 即每個環境都可以向上搜尋作用域鏈,以查詢變數和函式
  4. 任何環境不能向下搜尋作用域鏈而進入另一環境

上面程式碼等價於下

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





相關文章