2013-07-31 74 views
9

我寫的代碼如下內的對象,我可以使用的功能相同的功能

function Myfunction(){ 
Myfunction.myvar = "somevar"; 
} 

後,我執行的功能,我可以能夠訪問​​

它是如何工作的?如果我這樣做,那麼隱藏在這個問題中的是什麼?

如果有任何問題,請解釋上下文。

+0

【靜態的可能的複製JavaScript中的變量](http://stackoverflow.com/questions/1535631/static-variables-in-javascript/1535687#1535687) – Givi

+0

在js函數中也是對象,所以你可以給它添加一個屬性, –

+1

看一看[ *** jsFiddle ***](http://jsfiddle.net/GKDev/TdF94/)*也許這就是你想知道的。* – Givi

回答

5

它是如何工作的?

當您在某個執行上下文中聲明函數時,將綁定添加到該上下文的變量環境中。當您引用標識符時,將檢查當前變量環境以查看該標識符是否存在綁定。

如果不存在綁定,則檢查外部變量環境等等,以備份到全局範圍。

所以:

// OUTER SCOPE 
// Binding exists for 'example' 
function example() { 
    // INNER SCOPE 
    // No binding for 'example' 

    // References 'example' in outer scope 
    example.x = 1; 
} 

什麼問題隱藏在這個?

有沒有(一般來說...雖然是否正確的解決方案取決於你想要做什麼)。

您正在有效地創建函數的「靜態」屬性。由於JavaScript函數是一流的,您可以像使用其他對象一樣設置屬性。


注意的行爲是不同的,如果你有一個名爲函數表達,而不是一個函數聲明:

var x = function example() { 
    // Identifier 'example' is only in scope in here 
}; 
+0

謝謝你的回答,簡單直接...... –

6

由於函數在調用之前不會執行,因此不會立即對​​進行求值。

一旦你調用它,函數定義已經安裝爲Myfunction,這樣它可以在你調用它的時候解決。

像下面這樣是行不通的:

var x = { 
     foo: 1, 
     bar: x.foo } // x does not exist yet. 
+0

+1,就這麼簡單。我有點困惑其他答案是關於什麼。 –

+0

是的,我接受它。有沒有代碼違規?這是否會影響任何性能? –

+0

比較什麼影響性能?引用封閉作用域中的任何其他對象並沒有什麼區別,並不重要的是你指的是函數本身或者完全不相關的東西。 – Thilo

0

在javascript中的每個功能都是一個對象。所以你可以添加任何自定義字段。

function A() {} 

A.somevar = 'this is custom field'; 

A.prototype.somevar2 = 'this is field in A proto'; 

所以,當你用A構造器創建新對象時,它將從原型獲取屬性。

var b = new A(); 
alert(b.somevar2); 
2

一個問題,你可能會因爲範圍界定的,作爲一個更復雜的例子顯示:

function Other() { 
    console.log("a) Other.Myvalue",Other.Myvalue); 
    Other.Myvalue=typeof Other.Myvalue==='undefined' ? 0 : Other.Myvalue+1; 
    console.log("b) Other.Myvalue",Other.Myvalue); 
} 
Other(); 
Other(); 

這將導致

a) Other.Myvalue undefined 
b) Other.Myvalue 0 
a) Other.Myvalue 0 
b) Other.Myvalue 1 

所以你真的綁定您的變量MYVAR到函數對象本身是一個單例,並且只存在一次(並且由函數定義本身在當前上下文中可能是全局上下文創建),而不是該對象的實例。但是,如果你只使用靜態值,不需要任何邏輯,它就像字面的形式,我不希望出現任何問題,其他的文字形式更方便:

var Other = { 
    Myvalue: "somevalue" 
}; 
+0

如果你調用沒有new運算符的函數構造函數,它會創建一個名爲Myvar的全局變量,因爲這將引用window對象,但是在嚴格模式下它會導致錯誤,因爲這將是未定義的。 [看看](http://jsbin.com/opoker/1/edit) – Givi

+0

我不是很清楚,我的第二個代碼塊var x = Myfunction();與該問題的原始代碼有關。一個名爲Myvar的全局變量(意味着在周圍的上下文中)只有在函數使用這個而不是函數名時纔會被創建。 –

+0

我編輯我的答案是更精確 –

相關問題