在JavaScript中this關鍵字的用法很靈活也很強大,但也往往給概念不清的初學者帶來混淆,如果在一個function中你不知道this代表什麼,那麼你也很難了解這個function的作用了。
在JavaScript中this代表了目前執行的上下文,它是動态綁定的,也就是說隻有到了function調用時才确定this所綁定的對象。是以我們隻要清楚的了解到一個function是如何被調用的,我們也就能清楚的知道this綁定的是什麼對象。在JavaScript中function一共有4種調用模式:
1.方法調用模式
當一個函數被儲存為對象的一個屬性時,這個函數就被成為方法。是以當一個方法被調用時,this就綁定到該對象:
var myObject = {
value: 0,
increment: function () {
this.value += 1;
}
};
myObject.increment();
alert(myObject.value); //1
myObject.increment();
alert(myObject.value); //2
從上面的例子我們可以看到在myObject.increment()方法中,this綁定到myObject對象,并通過this去通路該對象的value屬性。
2.函數調用模式
當一個函數并非一個對象的屬性時(除了全局對象),那麼它就被當作一個函數來調用,當函數以此模式來調用時,this将被綁定到全局對象。這很容易了解,但是需要注意的是,一個内部函數被調用時,this仍然是被綁定到全局對象,比如:
myObject.someMethod = function () {
this.value = 2;
return function () {
alert(this.value); //undefined
};
};
var method = myObject.someMethod();
method(); //undefined
我們可以看到,someMethod中在内部傳回了一個匿名函數,在這個函數中this綁定的不是外部函數someMethod的this變量(即myObject),而是全局對象,因為我們沒有定義全局變量value,是以顯示的結果為undefined。如果我們需要将内部函數的this也綁定到myObject對象,我們可以這樣做:
myObject.someMethod = function () {
this.value = 2;
var that = this;
return function () {
alert(that.value); //2
};
};
var method = myObject.someMethod();
method(); //2
3.構造器調用模式
所謂的構造器模式就是使用new關鍵字來調用一個函數,這樣将建立一個隐藏連結到該函數的prototype成員的新對象,并且this關鍵字将會綁定到那個新對象上。
function Person()
{
this.age = 20;
}
var person = new Person();
alert(person.age); //20
當然,我們應當要注意:如果在調用Person()時,沒有使用new關鍵字,this将會綁定到全局對象上,這樣很可能會造成全局變量污染!!
4.Apply調用模式
因為JavaScript是一門函數式的語言(糅合了c文法),是以函數也是對象,可以擁有方法。
函數的apply方法讓我們建構一個參數數組并用其去調用函數,它也允許我們選擇this所綁定的值。apply方法接受兩個參數,第一個參數是指定this所綁定的值,第二個就是參數數組:
function add(a, b) {
return a + b;
}
var array = [3, 4];
var result = add.apply(null, array); //這裡将add中的this指定為null
alert(result);
另外,函數對象還有call方法與apply方法類似,隻是将參數數組改為參數清單。
總結:我們隻要搞清楚一個函數他是如何被調用的,就能清楚的知道this所綁定的值,這樣就不容易混淆了