2010-10-07 121 views
2

我見過一堆示例,但似乎無法獲得一些示例代碼。關閉裏面的「this」關鍵字

看看下面的代碼:

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     } 
    } 
}()); 

,我有一個功能上window.load像:

test.alertT(); 

這一切工作正常。但是,當我試圖明確地設置t的內部警報()alertT,我只是不明確。

我已經試過:

var that = this; 
alert(that.t); //undefined 

我已經試過:

 return { 
      that: this, 
      alertT: function(){ 
       alert(that.t); // undefined! 
      } 
     } 

,我已經試過:

var test = (function(){ 
    var t = "test"; 
    var myObj = this; 
    return { 
     alertT: function(){ 
      alert(myObj.t); // undefined! 
     } 
    } 
}()); 

我缺少什麼?我需要能夠明確地設置上下文等回調等我見過的例子(http://stackoverflow.com/questions/346015/javascript-closures-and-this-context),看起來像我在做什麼,那爲什麼這不起作用?

+0

爲什麼你想明確地設置上下文?你的例子並沒有真正表明這一點。要麼你必須傳遞一個上下文到alertT函數中,否則你將不得不使用綁定方法將函數綁定到你的選擇的上下文。 – Jakob 2010-10-07 16:32:23

+0

這個例子被忽略了,所以它很容易閱讀。我希望能夠顯式地訪問封閉的over變量,以便將其傳遞給另一個傳入的函數。 – hackerhasid 2010-10-07 16:35:25

回答

1

t只是外部匿名函數(因此也是內部匿名函數)範圍內的一個普通變量。它不是一個物體上的屬性,所以只需簡單地將其設置爲this,thatthe_other即可。

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     }, 
     setT: function (new_value) { 
      t = new_value; 
     } 
    } 
}()); 
test.alertT(); 
test.setT('hello, world'); 
test.alertT(); 

您正在使用的語法是用於創建類似於JS中的私有變量的通常模式。

+0

我無法弄清楚什麼statichippo要求,直到我看到你的答案。我猜他認爲「this」是對包含閉包變量的作用域的引用?很好的解釋。我的建議是不要使用「this」,除非你寫OO「class like」代碼,其中「this」指的是被操縱的對象,這個例子可以很容易地改變。但正如你所提到的,這個模塊patttern給你真正的私有變量(這使得它更難調試) – 2010-10-07 18:05:34

1

t不在'this'的範圍之內。 t是該方法的局部變量。所以,地方你需要做的

this.t = whatever 

...

這裏是一個應用程序我寫

var scope = this; 

cells.forEach(function(cell, index) { 
      var given = cell.get('given'); 

      var value = cell.get('value'), 
          valueAsString = '%@'.fmt(value); 


      var rowValues = scope.getRowForIndex(index); 
      ... 
} 

在foreach函數內部的範圍現實生活中的例子的範圍我正在迭代的數組'單元'。因爲我想在呼叫範圍上做些事情,所以我使用閉包...

+0

是的。但這也可能是一個壞主意。如果「this」是該方法中的全局對象,則會創建一個全局變量。 – Jakob 2010-10-07 16:31:03

+0

但是由於這是一個閉包,如果我只是引用t,那麼我得到閉包,因爲函數本身不包含任何t變量。我非常有興趣知道如何在方法中明確地引用閉合的t。 – hackerhasid 2010-10-07 16:32:30

+0

@jakob,絕對。似乎OP只是試圖瞭解範圍如何在閉包中工作,這僅僅是一個例子 – hvgotcodes 2010-10-07 16:33:09

0

在C#和Java,可以做這樣的事情:

public class MyClass { 
    private int x; 

    public void DoSomething(int x) { 
     int a = this.x; 
     int b = x; 
    } 
} 

變量A和B將具有值從不同的x的,因爲一個是類的X的一個是方法X。

現在,想象一下,如果你不能使用this來顯式引用該類的x。那麼你必須做到以下幾點:

public class MyClass { 
    private int classX; 

    public void DoSomething(int x) { 
     int a = classX; 
     int b = x; 
    } 
} 

這是我在JavaScript中的情況,非常多。至少在你描述的情況下。通過使用方法applycall,您可以更改執行函數的上下文,但不能區分具有相同名稱但範圍不同的變量。你只需要使用不同的名稱。