你不知道的javascript(上卷)
阿新 • • 發佈:2018-12-20
作用域
LHS & RHS 賦值操作的左右側 賦值操作的目標(LHS) 誰是賦值的源頭(RHS)
兩種工作模型
詞法作用域
只會查詢一級識別符號
欺騙詞法作用域:
eval()
在嚴格模式下,會有自己的詞法作用域,意味著其中的宣告無法修改其所在的作用域;
with()
會建立一個單獨的作用域,儘量不要使用
表面看 javascript沒有塊級作用域
使用 try … catch 語句 catch中為塊級作用域
先有雞還是先有蛋
先聲明後賦值;[案例已懂]
作用域閉包
將內部函式傳遞到所在詞法作用域之外,它會始終持有對原始定義作用域的引用,無論在何時執行這個函式都會使用閉包;
function a() {
var a = 3;
function b() {
console.log(a);
}
return b;
}
var c = a() ;
閉包應用廣泛,隨便舉幾個例子:
function wait(msg) {
setTimeout(function timer(){
console.log(msg);
},1000);
}
wait('wait for a second!');
函式 timer() 傳遞給 setTimeout,timer函式持有對wait() 作用域的閉包。同時保持對msg的引用; 還有 ajax請求,跨視窗通訊,web Workers, 只要使用了回撥函式,實際上就是使用閉包
經典迴圈閉包問題
- 因為沒有在IIFE中寫入任何內容,相當於是一個空殼,所以結果還是 6;
for(var i = 1; i<= 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i*1000)
})()
}
- 在IIFE中進行賦值,並通過引數進行傳遞
for(var i = 1; i<= 5; i++) { (function(j) { setTimeout(function() { console.log(j); }, j*1000) })(i); }
附錄
詞法作用域
正確使用和包含this機制
var obj = {
count: 0,
cool: function coolFn() {
if(this.count <1){
setTimeout(()=> {
console.log("cool");
},100);
}
}
}
var cool = "outside is not cool";
var obj = {
count: 0;
cool: function coolFn() {
setTimeout(function timer()
{
if(this.count<1){
console.log("cool");
}
}.bind(this),100) ;
}
}