2011-03-01 72 views
9

我一段時間都在爲JavaScript問題苦苦掙扎,我無法在網上找到解釋。我想這是因爲我沒有輸入正確的關鍵字,這也可能與我爲什麼一直在掙扎。javascript函數是對象嗎?

我的基本假設是,它是可以改變的對象:

> var x = {'n': 2}; 
> x['n'] 
2 
> x['n'] = 3; 
3 

pheww奏效。但仍然(功能也是對象):

> var addn = function(a) { 
    var n = 2; 
    return n + a; 
} 

> addn(3); 
5 
> addn['n'] = 3; 
3 
> addn(3); 
5 

這次我不能改變'n'。有沒有辦法解決這個問題,同時保持功能的味道?而不是完全OO。我有一個相關的問題,就是如何維護函數的依賴關係,以便進行測試 - 再次不用OO?因爲我正在尋找解決方案,但如果可能的話,我還想了解Javascript中的哪種機制讓我掙扎。

乾杯,

馬克

免責聲明: 通過提OO我不原意說對OO什麼。而且我也不打算對VI或Emacs發表任何言論。如果我以某種方式傷害了你的感情,請跳過這一個。

+1

你總是可以傳入n作爲參數,但我認爲這不是你要求的。 – Orbit 2011-03-01 17:58:58

+2

_你是什麼意思_「這次我無法改變'n'」_? 'addn ['n']'返回'3'嗎? – 2011-03-01 18:00:49

+0

關於您的面向對象的評論:您正在嘗試*重新創建* OO,即使在JavaScript中已經做得足夠多了。 ;) – 2011-03-01 18:06:07

回答

5

如果我正確理解你的問題,你可以通過提供一個名稱的匿名函數和訪問函數對象的屬性:

var addn = function func(a) { 
    return func.n + a; 
}; 

addn['n'] = 3; 
addn(3); // returns 6 
+0

你可以訪問一個匿名函數的一個屬性,而不需要通過將它包含在parens中來引用它。 '(function(){})。prototype' – 2013-07-27 08:39:56

2

對象的屬性和局部變量在很大程度上是不相關的:

  • var n聲明的變量是 作用域到它在功能(即 它不是 功能外可見(通過關閉除外) )。

  • addn['n']添加一個名爲n 屬性addn,相當於在一個函數範圍 addn.n

14

私有變量和對象的屬性有2件非常不同的事情。該功能內部完全不可訪問該功能。

因此,在代碼運行後,addn.n == 3,但不同的值設置爲var n會在每次運行該功能時被初始化。由於JavaScript的怪癖,一個函數不能真正地訪問它自己的屬性非常容易。相反,通過傳遞參數可以更好地實現此模式function(n, a)

或者使用對象來實現類似的功能。

var adder = { 
    n: 0, 
    addn: function(a) { 
    return this.n + a; 
    } 
}; 

adder.n = 5; 
adder.addn(2); // 7 
1

由於JavaScript有功能的範圍,你可以使用函數來存儲n的值,像這樣:

var addn = (function(n) { 
    return function(x) { 
    n += x; 
    return n; 
    } 
}(2); 

addn(3) // 5 
addn(3) // 8 
1

這是最好的,完全忘記在Javascript中「物」的傳統的面向對象概念而是考慮封閉。我強烈建議閱讀jQuery創建者John Resig的this tutorial

+0

來自你提到的教程: ' var num = 10; function addNum(myNum){ return num + myNum; } num = 15; assert(addNum(5)== 20,「將兩個數字加在一起,一個來自閉包。」); ' 我認爲這是一種方法,但有一件事我不喜歡,因爲'num'不再是'addn'對象的一部分。 – mark 2011-03-01 18:21:56

0

基本上,一切都在JavaScript是一個對象。如果你說

var a=3; 
a['n']=4; 

引用「A」仍然會返回3,但是也有一個成員「N」當你說你addn['n'] = 3添加新成員ADDN,而不是具有價值4。所以以任何方式影響功能。

我強烈推薦閱讀How good c habits can encourage bad javascript habits.在描述所有可以做錯的事情時,這是介紹Javascript中對象工作方式的一個很好的介紹。

0

首先,沒有被這樣改變功能變量:

ADDN [ 'N'] = 3;

您定義的函數沒有任何名稱(也稱爲「匿名函數」)。你只需要賦值給一個名爲addn的變量。一個變量沒有任何屬性 - 它只是一個容器(除非變量指向一個數組)。所以addn['n']什麼也沒有返回。

隨着用戶casablanca指出,可以你作爲func然後接入功能(和修改)其作爲func.<propertyname>性能。