在javascript中一共有四種調(diào)用模式:方法調(diào)用模式版保,函數(shù)調(diào)用模式,構(gòu)造器調(diào)用模式玩荠,apply調(diào)用模式
這些模式在如何初始化關(guān)鍵參數(shù)this上存在差異辛块。
1 方法調(diào)用模式(也就是用"."的方式來調(diào)用的)
當一個函數(shù)被保存為對象的一個屬性時,我們稱它為一個方法槐沼。當一個方法被調(diào)用時曙蒸,this被綁定到該對象捌治。如果一個調(diào)用表達式包含一個屬性存取表達式(即一個.點表達式或者[subscript]下標表達式),那么它被當做一個方法來調(diào)用
var myObject = {
value :0;
increment:fucntion (inc){
this.value += typeof inc ==='number' ? inc:1;
}
};
myObject.increment();
document.writeln(myObject.value); //1
myObject.increment(2);
document.writeln(myObject.value); //3
方法可以使用this去訪問對象,所以它能從對象中取得或修改該對象纽窟。this到對象的綁定發(fā)生在調(diào)用的時候具滴。這個“超級”遲綁定( very late binding)使得函數(shù)可以對this高度復(fù)用。通過this可取得它們所屬對象的上下文的方法稱為公共方法师倔。
2 函數(shù)調(diào)用模式
當一個函數(shù)并非一個對象的屬性是构韵,那么它被當做一個函數(shù)來調(diào)用:
var sum = add(3,4); //sum的值為7
當函數(shù)以此模式調(diào)用時,this被綁定到全局對象趋艘。這是語言設(shè)計上的一個錯誤疲恢,倘若語言設(shè)計正確,當內(nèi)部函數(shù)被調(diào)用時瓷胧,this應(yīng)該仍然綁定到外部函數(shù)的this變量显拳。這個設(shè)計錯誤錯誤的后果是方法不能利用內(nèi)部函數(shù)來幫助它工作,因為內(nèi)部函數(shù)的this被綁定了錯誤的值搓萧,所以不能共享該方法對對象的訪問權(quán)杂数。幸運的是,有一個很容易的解決方案:如果該方法定義一個變量并給他賦值為this瘸洛,那么內(nèi)部函數(shù)就可以通過那個變量訪問到this揍移。
//給myObject增加一個double方法
myObject.double = function(){
var that = this; //解決方案
var helper = function(){
that.value = add(that.value,that.value);
};
helper();//以函數(shù)的形式調(diào)用helper
};
//以方法的形式調(diào)用double
myObject.double();
document.writeln(myObject.getValue()); //6
3、構(gòu)造器調(diào)用模式:
調(diào)用形式:在函數(shù)名前加 new 來調(diào)用反肋。
this綁定:將創(chuàng)建一個隱藏連接到該函數(shù)的 prototype 成員的新對象那伐,同時 this 將會被綁定到這個新對象上。
例子:
// 創(chuàng)建一個名為 Quo 的構(gòu)造器函數(shù)石蔗。它構(gòu)造一個帶有 status 屬性的對象罕邀。
var Quo = function (string) {
this.status = string;
};
// 給 Quo 的所有實例提供一個名為 get_status 的公共方法
Quo.prototype.get_status = function () {
return this.status;
};
注意:在JavaScript中如果用 new 方式調(diào)用一個函數(shù),如果函數(shù)沒有返回一個對象养距,則返回 this诉探。
下面在用 new 調(diào)用 Quo 這個構(gòu)造函數(shù)時,因為 Quo 函數(shù)沒有返回值棍厌,所以默認返回 this gei myQuo肾胯。
// 構(gòu)造一個 Quo 實例
var yQuo = new Quo("confused"); // myQuo 的值被賦予了 this,而此時的 this 是 Quo 的 prototype 成員定铜。
document.writeln(myQuo.get_status()); // confused this.status 即 Quo.prototype.status 在調(diào)用 new 構(gòu)造 Quo 時即被賦予了 confused阳液。
document.writeln(myQuo.status); // confused
如果調(diào)用構(gòu)造器函數(shù)時前面沒有加 new,將會發(fā)生錯誤:
var myQuo = Quo("confused");
document.writeln(myQuo); // undefined 可見揣炕,沒有用 new 調(diào)用構(gòu)造器函數(shù)帘皿,它將不會有任何返回值給 myQuo。
4畸陡、Apply/Call調(diào)用模式:
調(diào)用形式:通過apply/call方法調(diào)用函數(shù)鹰溜,其中第一個參數(shù)為我們指定的 this 的值虽填。
this綁定:允許我們選擇 this 的值。
例子:
// 構(gòu)造一個包含兩個數(shù)字的數(shù)組曹动,通過apply方法調(diào)用前面的add函數(shù)斋日,將數(shù)組中的數(shù)字相加
var array = [3, 4];
var sum = add.apply(null, array); // sum的值為7。add()中沒有使用到 this 所以參數(shù)給其設(shè)為 null 即可墓陈。
例子:
// 構(gòu)造一個包含 status 成員的對象恶守,通過 apply 方法調(diào)用前面的 Quo對象的get_status 方法返回 status。
var statusObject = {
status : 'A-OK'
};
var status = Quo.prototype.get_status.apply(statusObject); // status 值為'A-OK' 在通過 apply 調(diào)用 Quo 的 get_status 方法時將 statusObject 對象綁定給了 this 贡必,所以 get_status 方法返回的結(jié)果是 statusObject 的 status 屬性兔港。