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