js中this的四種調(diào)用模式

在javascript中一共有四種調(diào)用模式:方法調(diào)用模式,函數(shù)調(diào)用模式,構(gòu)造器調(diào)用模式,apply調(diào)用模式
這些模式在如何初始化關(guān)鍵參數(shù)this上存在差異。
1 方法調(diào)用模式(也就是用"."的方式來(lái)調(diào)用的)
當(dāng)一個(gè)函數(shù)被保存為對(duì)象的一個(gè)屬性時(shí),我們稱它為一個(gè)方法。當(dāng)一個(gè)方法被調(diào)用時(shí),this被綁定到該對(duì)象。如果一個(gè)調(diào)用表達(dá)式包含一個(gè)屬性存取表達(dá)式(即一個(gè).點(diǎn)表達(dá)式或者[subscript]下標(biāo)表達(dá)式),那么它被當(dāng)做一個(gè)方法來(lái)調(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去訪問(wèn)對(duì)象,所以它能從對(duì)象中取得或修改該對(duì)象。this到對(duì)象的綁定發(fā)生在調(diào)用的時(shí)候。這個(gè)“超級(jí)”遲綁定( very late binding)使得函數(shù)可以對(duì)this高度復(fù)用。通過(guò)this可取得它們所屬對(duì)象的上下文的方法稱為公共方法。

2 函數(shù)調(diào)用模式

當(dāng)一個(gè)函數(shù)并非一個(gè)對(duì)象的屬性是,那么它被當(dāng)做一個(gè)函數(shù)來(lái)調(diào)用:
var sum = add(3,4); //sum的值為7
當(dāng)函數(shù)以此模式調(diào)用時(shí),this被綁定到全局對(duì)象。這是語(yǔ)言設(shè)計(jì)上的一個(gè)錯(cuò)誤,倘若語(yǔ)言設(shè)計(jì)正確,當(dāng)內(nèi)部函數(shù)被調(diào)用時(shí),this應(yīng)該仍然綁定到外部函數(shù)的this變量。這個(gè)設(shè)計(jì)錯(cuò)誤錯(cuò)誤的后果是方法不能利用內(nèi)部函數(shù)來(lái)幫助它工作,因?yàn)閮?nèi)部函數(shù)的this被綁定了錯(cuò)誤的值,所以不能共享該方法對(duì)對(duì)象的訪問(wèn)權(quán)。幸運(yùn)的是,有一個(gè)很容易的解決方案:如果該方法定義一個(gè)變量并給他賦值為this,那么內(nèi)部函數(shù)就可以通過(guò)那個(gè)變量訪問(wèn)到this。

//給myObject增加一個(gè)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 來(lái)調(diào)用。
this綁定:將創(chuàng)建一個(gè)隱藏連接到該函數(shù)的 prototype 成員的新對(duì)象,同時(shí) this 將會(huì)被綁定到這個(gè)新對(duì)象上。
例子:

//  創(chuàng)建一個(gè)名為 Quo 的構(gòu)造器函數(shù)。它構(gòu)造一個(gè)帶有 status 屬性的對(duì)象。
var Quo = function (string) {
    this.status = string;
};
//  給 Quo 的所有實(shí)例提供一個(gè)名為 get_status 的公共方法
Quo.prototype.get_status = function () {
    return this.status;
};

注意:在JavaScript中如果用 new 方式調(diào)用一個(gè)函數(shù),如果函數(shù)沒(méi)有返回一個(gè)對(duì)象,則返回 this。
下面在用 new 調(diào)用 Quo 這個(gè)構(gòu)造函數(shù)時(shí),因?yàn)?Quo 函數(shù)沒(méi)有返回值,所以默認(rèn)返回 this gei myQuo。
// 構(gòu)造一個(gè) Quo 實(shí)例

var yQuo = new Quo("confused");    //  myQuo 的值被賦予了 this,而此時(shí)的 this 是 Quo 的 prototype 成員。
document.writeln(myQuo.get_status());    //  confused    this.status 即 Quo.prototype.status 在調(diào)用 new 構(gòu)造 Quo 時(shí)即被賦予了 confused。
document.writeln(myQuo.status);    //  confused

如果調(diào)用構(gòu)造器函數(shù)時(shí)前面沒(méi)有加 new,將會(huì)發(fā)生錯(cuò)誤:

var myQuo = Quo("confused");
document.writeln(myQuo);    //  undefined    可見(jiàn),沒(méi)有用 new 調(diào)用構(gòu)造器函數(shù),它將不會(huì)有任何返回值給 myQuo。

4、Apply/Call調(diào)用模式:
調(diào)用形式:通過(guò)apply/call方法調(diào)用函數(shù),其中第一個(gè)參數(shù)為我們指定的 this 的值。
this綁定:允許我們選擇 this 的值。
例子:
// 構(gòu)造一個(gè)包含兩個(gè)數(shù)字的數(shù)組,通過(guò)apply方法調(diào)用前面的add函數(shù),將數(shù)組中的數(shù)字相加

var array = [3, 4];
var sum = add.apply(null, array);    //  sum的值為7。add()中沒(méi)有使用到 this 所以參數(shù)給其設(shè)為 null 即可。

例子:
// 構(gòu)造一個(gè)包含 status 成員的對(duì)象,通過(guò) apply 方法調(diào)用前面的 Quo對(duì)象的get_status 方法返回 status。

var  statusObject = {
    status : 'A-OK'
};
var status = Quo.prototype.get_status.apply(statusObject);    //  status 值為'A-OK'  在通過(guò) apply 調(diào)用 Quo 的 get_status 方法時(shí)將 statusObject 對(duì)象綁定給了 this ,所以 get_status 方法返回的結(jié)果是 statusObject 的 status 屬性。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容