首頁 >web前端 >js教程 >Javascript淺談之this_基礎知識

Javascript淺談之this_基礎知識

WBOY
WBOY原創
2016-05-16 17:08:46965瀏覽

介紹
this在各種對面物件程式設計中起著非常重要的作用,主要用於指向調用的物件。不過在JavaScript中,this的表現有很大差異,特別是不同執行上下文。

由前文我們知道this也是屬於執行上下文中的一個屬性,所有它命中註定和執行上下文脫不了乾系。

複製程式碼 代碼如下:

activeExecutionContext = {

this: thisValue};

在Javascript中,this的取值取決於呼叫的模式。呼叫模式總共有四種:方法呼叫模式、函式呼叫模式、建構器呼叫模式和apply呼叫模式。


呼叫模式

方法呼叫模式

當一個函數被儲存為物件的屬性時,我們稱它為一個方法。當一個方法被呼叫時,this被綁定到該對象,也就是方法呼叫模式中的this指向呼叫對象。這個理解起來非常容易,你是我的一個方法,你屬於我,你的this當然指向我啦。

程式碼如下:


var myObject = { 🎜>        increment : function(inc) {
             this.value = typeof inc  
myObject.increment();
console .log(myObject.value);  //輸出:1
myObject.increment(3);
console.log(myObject.value);   //輸出:4



因為可以透過this存取到自己所屬的對象,所有可以透過它來呼叫和修改對像中屬性或方法。由前文可知,this作為執行上下文中屬性的一員,必然是在上下文創建時才創建,所有this到對象的綁定發生在調用的時候,這屬於「延遲綁定」。透過延遲綁定可以實現this的高度復用。

複製程式碼 程式碼如下:f this.value); 
}
var a = { value : "a"};
var b = { value : "b"};
a.showValue = showValue;
b .showValue = showValue;
a.showValue();  //輸出「a」
b.showValue();  //輸出「b」



上例中函數showValue就屬於延遲綁定。

函數調用模式

當一個函數並非作為一個物件的方法來調用,這時就是函數調用。函數呼叫模式中,this被綁定到全域物件。 (這是語言設計上的錯誤)

複製程式碼

程式碼如下:my that = this;   //解決方法    var helper = function(){
        console.log(that, ": ", that.value); //輸出 {value: 4unction increment: function, double.value); //輸出: function} ": " 4
        console.log(this, ": ", this.value); //輸出  Window {top: Window, window: Window…} ": " undefined }    helper(); //以函數形式呼叫
}

依照正常思路,應該如第四行所輸出那樣,this指向函數所屬對象,可是由於語言設計上面的問題導致this指向的卻是全局對象。這個更是讓this變得神秘,令人捉摸不透。但是作為開發者,這種情況肯定是我們所不願意見到的,不按常理出牌這是,還好補救措施也很簡單,就是上例中用that指代this。這樣,在helper方法中呼叫that就可以當this使用,簡單方便。至於函數呼叫模式為什麼this會這樣,後面在分析引用型別時會詳加說明。

建構器呼叫模式
由於javascript是基於原型繼承,但是它的設計者又想要它能像傳統的物件導向語言那樣能透過new和建構函數創建對象,現實面向對象程式設計。這個似乎不是什麼好的構想,有點畫虎不成反類犬的尷尬。一是學不來,而是沒必要學。 javascript的原型繼承機制已經非常強大,足以滿足物件導向所需的繼承多型。

閒話少敘,還行言歸正傳說說構造器調用模式。建構器呼叫模式這個非常簡單,它就是就一個函數當做建構器,然後將你打算公用的屬性和方法用this引進宣告。如下

複製程式碼 程式碼如下:

f .name = name;
        this.age = age;
        this.say = function(){
  this. age);
       }
}
var p1 = new Person("jink", 24);

p1.say(); //輸出  name : jink, age : 24

var p2 = new Person("張三", 33);

p2.say();//輸出  name : 張三, age : 33

上面例子我們可以清楚看出,this是指向透過new和建構子所建立的物件。為什麼會這樣呢?這是因為在javascript中透過new呼叫建構函式時,new運算子呼叫「Person」函數的內部的[[Construct]] 方法,接著,在物件建立後,呼叫內部的[[Call]] 方法。 所有相同的函數「Person」都將this的值設定為新建立的物件。

apply呼叫模式
javascript中所有函數創建之後,都會自帶兩個方法:apply和call。這兩個方法的具體使用,我在此就不想詳細說明,不知道的同學可以百度一下,挺簡單的。透過兩個方法,我們可以手動設定this。雖然this在創建時候是不允許修改的,但是,我們在創建之前,手動設定過,那就是另外一回事了。這個設置,可不得了,你就可以讓你的對象調用任意方法,就好像你可以讓汽車大海中航行,非洲像如美洲豹一樣飛馳,程式設計師像鋼琴師一樣彈奏。哈哈想像總是美好的,調用歸調用,但是調用了能不能實現功能就另說了。

複製程式碼 程式碼如下:
var programmer = {  ",
    hand : "靈活的雙手",
    programme : function(){
        console.log(this.name "使用🎜>}

var pianist = {
    name : "鋼琴家",
    hand : "彈性的雙手",     play : function(){     }
}

var player = {
    name : "運動員",
    foot : "矯健的雙腿",
    this.foot "在賽場上賓士。");    }

}

//循規蹈矩
programmer.programme(); //程式設計師用靈活的雙手寫程式碼。
pianist.play(); //鋼琴家用靈活的雙手彈奏動聽的樂曲。
player.run(); //運動員用矯健的雙腿在賽場賓士。
//異想天開

pianist.play.apply(programmer); //程式設計師用靈活的雙手彈奏動聽的樂曲。

player.run.apply(programmer); //程式設計師用undefined在賽場上賓士。   由於自身運動缺乏,沒有矯正的雙腿

上面看著是不是挺有意思的,apply的第一個參數就是執行方法中的this指向。這樣我們就可以藉用別人的方法自己私下偷偷的用,可謂方便至極。在一些框架中常用的此類技巧。

總結
關於this就說這麼多,相信大家看過之後,對在不同情境中this的判定都有些了解了,本來打算討論接下來討論引用對象的,闡述一下方法呼叫模式和函數呼叫模式中this取值的原理,但害怕篇幅過長,所以決定用單獨一章向大家分析一下引用對象這個概念。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn