JS 事件迴圈,閉包,作用域鏈題

徐海東發表於2019-02-21
  • JS的事件迴圈機制

console.log('one')
setTimeout(function () {
    console.log('two')    
}, 0)
console.log('three')複製程式碼

輸出是

one
three
two複製程式碼

此題的關鍵是JS的事件迴圈機制,對非同步的處理操作,JS有句口令:同步優先、非同步靠邊、回撥墊底。

第一個console.log是同步執行,直接輸出one

執行完遇到setTimeout回撥(墊底執行),把setTimeout丟到回撥訊息佇列等待

然後console.log('three')也是同步執行,直接輸出three,同步的訊息佇列全部執行完後輪到回撥佇列執行輸出two

  • 閉包與作用域相關題目

function test() {
    var n = 4399;
    function add() {
        n++;
        console.log(n);
    }
    return {
        n: n,
        add: add
    }
}
var result = test(); 
var result2 = test(); 
result.add();
result.add(); 
console.log(result.n); 
result2.add(); 
複製程式碼

輸出

4400
4401
4399
4400複製程式碼

此題的關鍵在於明白var result = test() 與var result2 = test()此處分別產生了兩個閉包,它們之間是獨立,互不干擾的

閉包的產生:在A函式中定義了B函式,B函式中引用了A函式中的變數,此時會產生閉包

var result = test()  // 設定result的屬性為: { n:4399, add: add() }
var result2 = test()  // 設定result2的屬性為: { n:4399, add: add()  }result.add() // 呼叫了result的add方法,執行n++,所以n = 4399 + 1 輸出4400
result.add() // 再次呼叫了result的add方法,此時n = 4400 所以n = 4400 + 1 輸出4401

console.log(result.n)  //這是輸出result的屬性n值,輸出4399,這裡是輸出物件屬性返回值,並無呼叫閉包

result2.add() // 呼叫了result2的add方法,此時n = 4399 所以n = 4399 + 1 輸出4400

複製程式碼

 

  • 作用域鏈的題目

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);
	console.log(self.foo);
	(function() {
	    console.log(this.foo);
	    console.log(self.foo);
	}());
    }
};
myObject.func();
複製程式碼

輸出

bar
bar
undefined
bar複製程式碼

此題關鍵理解: 方法或函式由誰呼叫,方法函式內部的this就指向誰

1、func由myObject呼叫,this指向myObject,輸出bar

2、self 指向myObject,輸出bar

3、立即執行匿名函式表示式由window呼叫,this指向window

4、立即執行執行函式在本作用域找不到self,沿著作用域鏈向上尋找self變數,找到了父函式中指向myObject物件的self


相關文章