首頁  >  文章  >  web前端  >  JavaScript中的this關鍵字使用方法總結_javascript技巧

JavaScript中的this關鍵字使用方法總結_javascript技巧

WBOY
WBOY原創
2016-05-16 16:09:42875瀏覽

在javascritp中,不一定只有物件方法的上下文才有this, 全域函數呼叫和其他的幾種不同的上下文中也有this指涉。
它可以是全域對象、目前對像或任意對象,這完全取決於函數的呼叫方式。 JavaScript 中函數的調用有以下幾種方式:作為物件方法調用,作為函數調用,作為構造函數調用,和使用 apply 或 call 調用。

1.作為物件方法呼叫

在 JavaScript 中,函數也是對象,因此函數可以作為一個對象的屬性,此時該函數被稱為該對象的方法,在使用這種調用方式時,this 被自然綁定到該對象。

複製程式碼 程式碼如下:
 
var point = {
x : 0,
y : 0,
moveTo : function(x, y) {
    this.x = this.x x;
    this.y = this.y y;
    }
};
point.moveTo(1, 1)//this 綁定到目前對象,即 point 物件

2.作為函數呼叫

函數也可以直接被調用,此時 this 綁定到全域物件。在瀏覽器中,window 就是該全域物件。例如下面的例子:函數被呼叫時,this 被綁定到全域對象,接下來執行賦值語句,相當於隱式的宣告了一個全域變量,這顯然不是呼叫者希望的。

複製程式碼 程式碼如下:
 
function makeNoSense(x) {
this.x = x;
}
makeNoSense(5);
x;// x 已成為一個值為 5 的全域變數

對於內部函數,也就是宣告在另一個函數體內的函數,這種綁定到全域物件的方式會產生另外一個問題。我們仍然以前面提到的 point 物件為例,這次我們希望在 moveTo 方法內定義兩個函數,分別將 x,y 座標進行平移。結果可能出乎大家意料,不只 point 物件沒有移動,反而多出兩個全域變數 x,y。

複製程式碼 程式碼如下:

var point = {
x : 0,
y : 0,
moveTo : function(x, y) {
    // 內部函數
    var moveX = function(x) {
    this.x = x;//this 綁定到了哪裡?
   };
   // 內部函數
   var moveY = function(y) {
   this.y = y;//this 綁定到了哪裡?
   };

   moveX(x);
   moveY(y);
   }
};
point.moveTo(1, 1);
point.x; //==>0
point.y; //==>0
x; //==>1
y; //==>1

這屬於JavaScript 的設計缺陷,正確的設計方式是內部函數的this 應該綁定到其外層函數對應的物件上,為了規避這個設計缺陷,聰明的JavaScript 程式設計師想出了變數替代的方法,約定俗成,該變數一般被命名為that。

複製程式碼 程式碼如下:

var point = {
 x : 0,
 y : 0,
 moveTo : function(x, y) {
      var that = this;
     // 內部函數
     var moveX = function(x) {
     that.x = x;
     };
     // 內部函數
     var moveY = function(y) {
     that.y = y;
     }
     moveX(x);
     moveY(y);
     }
 };
 point.moveTo(1, 1);
 point.x; //==>1
 point.y; //==>1

作為建構子呼叫

JavaScript 支援物件導向式編程,與主流的物件導向程式語言不同,JavaScript 並沒有類別(class)的概念,而是使用基於原型(prototype)的繼承方式。對應的,JavaScript 中的建構函數也很特殊,如果不使用 new 調用,則和普通函數一樣。作為另一個約定俗成的準則,建構函式以大寫字母開頭,提醒呼叫者使用正確的方式呼叫。如果呼叫正確,this 綁定到新建立的物件上。

複製程式碼 程式碼如下:

function Point(x, y){
   this.x = x;
   this.y = y;
}

使用 apply 或 call 呼叫

讓我們再一次重申,在 JavaScript 中函數也是對象,對象則有方法,apply 和 call 是函數對象的方法。這兩個方法異常強大,他們允許切換函數執行的上下文環境(context),也就是 this 綁定的物件。很多 JavaScript 中的技巧以及類別庫都用到了這個方法。讓我們來看一個具體的例子:

複製程式碼 程式碼如下:

function Point(x, y){
   this.x = x;
   this.y = y;
   this.moveTo = function(x, y){
       this.x = x;
       this.y = y;
   }
}

var p1 = new Point(0, 0);
var p2 = {x: 0, y: 0};
p1.moveTo(1, 1);
p1.moveTo.apply(p2, [10, 10]);

在上面的範例中,我們使用建構子產生了一個物件p1,該物件同時具有moveTo 方法;使用物件字面量建立了另一個物件p2,我們看到使用apply 可以將p1 的方法套用到p2上,這時候this 也被綁定到物件p2 上。另一個方法 call 也具備同樣功能,不同的是最後的參數不是作為一個數組統一傳入,而是分開傳入的。

複製程式碼 程式碼如下:

function Foo(){
//1.this引用的建構子是argument.callee引用的物件
//說明是透過new操作符執行的建構子
if(this.constructor==arguments.callee){
alert('Object Created');
}
//2.this是window, 那麼是全域呼叫
if(this==window){
alert('normal call');
}
else{//3.否則是作為其他物件的方法來呼叫
alert('called by ' this.constructor);
}
}
Foo();//全域函數呼叫
Foo.call(new Object());//作為一個object物件的成員方法來呼叫
new Foo();//被new操作符調用,執行物件構造
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn