2012-12-17 30 views
0

如果我要使用Function構造函數創建一個新的function,除了window之外,我怎樣才能給它一個非臨時範圍(意味着範圍只需要被評估一次,而不是每次函數被調用時)?目的是構造多個變量,這些變量需要一些相當昂貴的計算,並且我不想在每次調用函數時都重構它們,但我也不想將它們存儲在window中。有任何想法嗎?如何在JavaScript中爲函數構造函數使用作用域?

回答

2

爲了上述目的,您使用靜態函數。您無法阻止範圍在每次調用時被評估,因爲這是JavaScript的工作方式,但您可以通過在範圍鏈中沒有window來加速範圍。

var namespace = {}; 
namespace.someMethod = function() { 
    // do something here. 
}; 

現在,在代碼中的任何位置,都可以使用namespace.someMethod();調用該方法。小心一點。以上是靜態方法。你可以在不實例化的情況下調用它。但是你在不可以使用this.property裏面的一個靜態函數。這是一個潛在的非常危險的操作,因爲它可能會擴展訪問全局對象並且基本上不受限制的權限。

而上述是一個static JavaScript方法。它在的範圍鏈中沒有窗口

以下是如何使用相同模式創建構造函數的方法。當你想使用構造函數時,你總是在使用之前實例化。爲此,您有new關鍵字。

var namespace = {}; 
namespace.coordinate = function(x, y) { 
    this.x = x; 
    this.y = y; 
}; 

namespace.coordinate.prototype.addCoordinates = function() { 
    return this.x + this.y; 


}; 

現在在你的代碼的任何地方,你可以這樣做:

var coordinateObject = new namespace.coordinate(5,10); 
// you have created a new instance. 
alert(coordinateObject.addCoordinates());// will alert 15; 
// now you can make as many as you want. They will behave as instances. 
// This means they do not interfere with each other in any way. 
// They just have the same properties and methods, but the instance values 
// Can be entirely different. 

var secondCoordinateObject = new namespace.coordinate(10, 25); 
alert(secondCoordinateObject.addCoordinates());// will output 35. 

您已經successufully創建了namespace.coordinate類的一個實例。使用我給你的模式,你幾乎可以複製Java或C或任何其他面嚮對象語言的全部功能。

+0

因此,我將變量存儲到'namespace',並通過函數內的'this [varName]'引用它們。我不能使用靜態函數,因爲我正在爲複雜的數學表達式編寫JavaScript編譯器。 –

+0

哦!我可以做'someMethod.call(namespace,arg0,arg1,... argN)'。我認爲這會很好! –

+0

事情是,功能是爲了一個特定的目的,只會因爲一個原因而被調用,所以另一個答案完全適用於我正在做的事情。 –

5

您可以將您的功能結合使用bind關鍵字的具體情況:

var context = {}; 
var f = new Function("args", "return this").bind(context); 
f(); // context 

由於綁定在ECMA 5定義,它可能不會出現在所有的瀏覽器,here's a workaround

+0

這甚至比'Function.prototype.call'好!謝謝! –

+0

感謝您的支持,但實際情況是,我的程序需要HTML5才能正常工作,因此如果瀏覽器不支持HTML5,則解決方法將毫無意義。 –

+0

那麼,問題解決了;) –

0

日益增長創建,存儲,隱藏,顯示和分組變量的方法&功能是通過「關閉」的魔術,Javascript的功能最強大但沒有功能:

var groupObj = (function (setUp) { 

    // maintained by reference, hidden 
    var _priVar = setUp * 2; 

    // maintained by reference, revealed (through returned object) 
    var _pubVar = 8;  
    var _pubFunc = function (x) {  
     _priVar += x; 
     _pubVar += x;  
    } 

    var lostVar = setUp * 99; // not referenced, hidden, so evaporates! 

    return {  
     'pubVar' : _pubVar, 
     'pubFunc' : _pubFunc  
    } 

}(4)); // runs immediately with 4 as setUp, revealing pubVar & pubFunc 

則...

groupObj.pubFunc(7); // runs public function, adds 7 to both variables 

alert('public variable: ' + groupObj.pubVar); // alerts public variable 

每當有另一個函數的內部函數時,發生關閉。只要外部函數內部的變量被內部函數引用,這種類型就是一個「無人地帶」,其中一個變量被強制從一個較低範圍引用而存在,但被隱藏從更高的範圍,由於JavaScript的先天原則。

還有其他一些方法可以使用閉包,取代對象構造函數,一次性無衝突的私有函數等等。這裏有很多關於他們的帖子。

0
var yourNamespace = { 

func1: function() { 
}, 

func2: function() { 
} 
}; 

... 

yourNamespace.func1(); 

您可以通過調用名稱空間中的函數來調用函數,如下所示:yourNamespace.func1();

相關問題