1、this的綁定
This是在運行時進行綁定的。並非在編寫時綁定的,他的上下文取決於函數調用時的各類條件。this的綁定與函數聲明的位置沒有任何關係,只取決於函數的調用方式。
2、this是什麼
當一個函數被調用時,會建立一個活動記錄(執行上下文)。這個記錄會包含函數在哪裏被調用、函數的調用方法、傳入的參數等信息。this就是記錄的其中的一個屬性,會在函數執行過程當中用到。
3、this的綁定規則
咱們能夠根據優先級來判斷函數在某個調用位置應用的是哪條規則。能夠按照下面的順序來進行判斷:
- 函數是否在new中調用(new綁定)?若是是的話this綁定的是新建立的對象。
var bar = new foo()
- 函數是否經過call、apply(顯式綁定)或者硬綁定調用?若是是的話,this綁定的是指定的對象。
var bar = foo.call(obj2)
- 函數是否在某個上下文對象中調用(隱式綁定)?若是是的話,this綁定的是那個上下文對象。
var bar = obj1.foo()
- 若是都不是的話,使用默認綁定。若是在嚴格模式下,就綁定到undefined,不然綁定到全局對象(window)。
var bar = foo()
就是這樣。對於正常的函數調用來講,理解了這些知識你就能夠明白 this 的綁定原理了。
4、注意
4.一、顯示綁定
function foo() {
console.log('this:', this); // Number(2)
}
foo.call( 2 );
|
雖然foo是一個引用,可是實際上,它引用的是foo函數自己,所以此時的foo()其實是一個不帶有任何修飾的函數調用,所以應用了默認綁定。
對於顯式綁定,若是傳入的是一個原始值(字符串類型,布爾類型或者數字類型)來當作this的綁定對象,這個原始值會被轉換爲它的對象形式,這一般被稱爲裝箱。
另外,當null或者undefined做爲this的綁定對象傳入call、apply或者bind,這些值在調用時會被忽略,實際應用的是默認綁定規則。
4.二、間接引用
函數在間接引用時,調用這個函數會應用默認綁定規則。
間接引用最容易在賦值時發生:
function foo() {
console.log('a: ', this.a); // Number(2)
}
var a = "global";
var obj = {
a: "part",
foo: foo
};
var p = { a: 2};
(p.foo = obj.foo)(); // global
p.foo(); // 2
|
賦值表達式p.foo = obj.foo的返回值是目標函數的引用,所以調用位置是foo()而不是p.foo()或者o.foo()。這裏會應用默認綁定
這裏關鍵是看究竟是誰在調用函數。