- 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