2014-02-26 57 views
0

我知道這個問題已經在這裏處理了很多,但我看到了這個具體的例子在Pluralsight JS設計模式課程,我會很高興你的幫助理解那裏的關閉。Javascript關閉&「that」而不是「this」在一個具體的例子

這是例子:

var Calc = function(start) { 
    var that = this; 

    this.add = function(x) { 
     start = start + x; 
     return that; 
    }; 

    this.multiply = function(x) { 
     start = start * x; 
     return that; 
    }; 

    this.equals = function(callback) { 
     callback(start); 
     return that; 
    }; 
} 

new Calc(0) 
    .add(1) 
    .add(2) 
    .multiply(3) 
    .equals(function(result){ 
     console.log(result); // returns 9 
    }); 

這裏的的jsfiddle鏈接:http://jsfiddle.net/3yJ8Y/5/

我會非常高興:

  1. 瞭解 「即」 使用。爲什麼我們在這個特定的 示例中需要它?它與「this」一樣。你能否舉出例子並解釋我們什麼時候需要做「var that = this」?
  2. 理解這種從對象創建函數的方式。爲什麼我們必須使用「this」和.functionName?像this.add = ...
  3. 這個非常具體的閉包例子的詳細和廣泛的解釋。

非常感謝!

+0

'that'實際上是錯在這裏(因爲它不是一個局部變量)。 '這個'會更好。 – Bergi

+0

在這種情況下,你不需要'that','this'會工作得很好,請參閱http://jsfiddle.net/3yJ8Y/2/ – elclanrs

+1

你對封閉的理解到底是什麼?在課程中沒有解釋,你在什麼時候迷路了? 'start'是每個'Calc'調用的局部變量。 – Bergi

回答

1

感謝@elclanrs提醒我的事情,我已經內化和遺忘......

這裏最重要的是,that ...是不必要的。

我會引述@elclanrs在他的評論鏈接對上述職位的文章:

Scope In Javascript

的JavaScript建立的函數調用的執行環境,此設置被引用的對象無論因爲每個方法被調用與外Calc這點之前,該this值insid前的最後一個」。」

來到e該方法被分配爲外部對象。

外對象,又是自己的全新的,自包含的範圍,因爲它是用new關鍵字創建:

new [Calc] ()被執行時,一個完全新的對象是在後臺透明地創建。 [Calc]被調用,並且其關鍵字被設置爲引用該新對象。

Scope in Javascript, again, with my edits in brackets)。

現在,你可能會想,「這是怎麼回事:

.add(1) 
.add(2) 
.multiply(3) 

...保持合適的範圍你說,無論是.傳入在這種情況下,this變量之前!??「

絕對真實的,在這種情況下,每個方法返回this,允許方法鏈接。(他們實際上返回that,但我們已經確定,在這種情況下不必要的變量)。

爲什麼要使用that

首先,讓我說,我更喜歡在var self = thisvar that = this有爭論無論哪種方式

讓我們隨意修改對象有看起來像這樣的方法:

所有的
this.getInternalThis = function(){ 
    var internalThis = function(){ 
     console.log(this); 
    } 
} 

首先,讓我們得到這個出路:這個例子是愚蠢的,但你會看到的東西像 - 所有的時間 - 在其他範圍內定義的函數。

這裏是要注意的重要的事情:

  1. 它的名字叫,僅此而已(沒有前綴.符號,例如)
  2. ...就是這樣!

當這樣調用一個函數時,引擎必須找出一些東西來指定this,就像函數的作用域一樣。它默認爲window。 如果您要運行此代碼,您將在控制檯中獲得Window

現在,如果我們想在該內部函數調用中的this作爲調用值this怎麼辦? 這個的情況是你需要一個that變量的地方。我們可以修改函數的樣子:

this.getInternalThis = function(){ 
    var that = this, 
     internalThis = function(){ 
      console.log(that); 
     }; 
} 

現在,當你運行這個方法,你在控制檯中調用對象的值。
在我的情況下,它是Object { add=function(), multiply=function(), equals=function(), getInternalThis=function()}

有時,這就是您所需要的或期望的,所以這就是您使用var that = this聲明的原因。

使用this.定義一個方法

正如我所提到前面:

由於每個方法調用與外Calc它的一個點之前,該方法內的this值被指定爲外部對象。

記住thisCalc()範圍爲計算器對象的引用,因此報錯計算器對象的this值每種方法(請記住,它.之前的!),當他們從這種情況下輸入他們的新範圍。

但願這給你如何JavaScript的範圍提供一些信息和this作品的分配。

+0

我認爲這個解釋是誤導性的,在這個函數被調用之前'this'沒有被分配給任何東西。它是'new'關鍵字,爲'this'創建一個新的對象,否則它將默認爲'window'。在這種情況下對'that'的引用是不必要的,因爲在實例上使用點符號隱式設置'this'爲接收者。使用原型並不會讓這個神奇地指向這個實例,而是您稱之爲重要函數的方式。 – elclanrs

+0

@elclanrs你說得很對。你可以編輯我的答案或張貼另一個清楚嗎? – rockerest

+0

非常感謝你們! – FED

0

start成爲Calc對象

Calc對象的每個方法的一個全局變量(addmultipleequals)引用同一個全局變量

new Calc(0)   // <- sets start to 0 
    .add(1)   // calls add() <- sets start to 1 
    .add(2)   // calls add() <- sets start to 3 
    .multiply(3)  // calls multiple() <- sets start to 9 
    .equals(function(result){ 
     console.log(result); // returns 9 
    });