1. 程式人生 > >你不知道的javascript(上卷)

你不知道的javascript(上卷)

作用域

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, 只要使用了回撥函式,實際上就是使用閉包

經典迴圈閉包問題
  1. 因為沒有在IIFE中寫入任何內容,相當於是一個空殼,所以結果還是 6;
for(var i = 1; i<= 5; i++) {
	(function() {
		setTimeout(function() {
			console.log(i);
		}, i*1000)	
    })()
}
  1. 在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) ;
	}
}