JS 事件循環,閉包,做用域鏈題

  • JS的事件循環機制

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

輸出是bash

one
three
two複製代碼

此題的關鍵是JS的事件循環機制,對異步的處理操做,JS有句口令:同步優先、異步靠邊、回調墊底。閉包

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

執行完遇到setTimeout回調(墊底執行),把setTimeout丟到回調消息隊列等待函數

而後console.log('three')也是同步執行,直接輸出three,同步的消息隊列所有執行完後輪到回調隊列執行輸出twoui

  • 閉包與做用域相關題目

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(); 
複製代碼

輸出this

4400
4401
4399
4400複製代碼

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

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

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就指向誰three

一、func由myObject調用,this指向myObject,輸出bar

二、self 指向myObject,輸出bar

三、當即執行匿名函數表達式由window調用,this指向window

四、當即執行執行函數在本做用域找不到self,沿着做用域鏈向上尋找self變量,找到了父函數中指向myObject對象的self

相關文章
相關標籤/搜索