2012-10-31 49 views
4

存儲參數所提供的數據在哪裏?隱含地創建了var first一個對象構造函數,它在構造函數體內使用參數但沒有「vars」,數據在哪裏?

function Student(first){ 
    this.getFirst = function(){ 
    return first; 
    } 
} 

測試用:

var myStudent = new Student("ross");

console.log(myStudent); //學生{getFirst =函數()}

console.log(myStudent.getFirst()); //羅斯

console.log(first); //參考誤差,第一不定義

console.log(myStudent.first); //未定義

for(var x in myStudent){ console.log(x); } // getFirst

我的第二個問題是,如果我這些正確理解:

What happens with "var" variables inside a JavaScript Constructor?

「var」 variables, "this" variables and "global" variables - inside a JavaScript Constructor

...是getFirst函數創建一個閉包並保存構造函數的參數值的狀態,如果我在構造函數中使用var first ctor身體是否可以認爲是「封裝」?此外,任何內部函數保存在一個「封閉狀態」或僅僅是一個人的由內部函數引用的所有參數值?

非常感謝你對你的思念。這是我對S.O的第一個問題。但幾乎每天都會使用該網站作爲參考,所以非常感謝。我的編程知識是有限的,所以如果我使用了蹩腳的術語,請高興地澄清需要的地方。

+0

函數中的'var'關鍵字「創建」一個變量,它的*範圍規則*與該函數的參數[variables]相同;反過來也是如此。 – 2012-10-31 03:00:02

回答

4

first參數存儲在本地,以那就是你的構造函數,裏面Student()所以任何地方它會在範圍之內。

更有趣的是,你要分配給this.getFirst的匿名內部功能收盤在該值。因此,即使在構造函數完成執行後,內部函數也會保持對變量first的引用。

這適用於常規的功能也不僅僅是構造函數:

function makeCounter() { 
    var count = 1; 
    return function() { return count++; }; 
} 

var counter = makeCounter(); 
console.log(counter()); // 1 
console.log(counter()); // 2 
console.log(counter()); // 3 

當使用正確的方法,這種方法可以用來實現在JavaScript中的「私人」的變量,在這個意義上,值捕獲封閉是從外部無法進入的。

因此,事實證明閉包捕獲其範圍內的所有變量或僅僅使用它所用的變量無關緊要,因爲無論如何您都無法「向內」伸向那些閉合變量。 (儘管在實踐中通常只捕獲所使用的值,以便運行時可以垃圾收集其餘部分,因爲它們不需要。)

+0

因此,如果不在構造函數的主體中明確包含任何屬性(包含getter/setter),就定義javascript構造函數,這將是一種合法的編碼策略?如果以這種方式完成,使用的內存是否與getter/setters分配給聲明屬性的內存使用方式不同?關閉會不管?如果是這樣,可能顯式聲明屬性是浪費? –

+0

無論是通過名稱作爲函數參數還是作爲函數內的局部變量引用對象,您擁有的所有閉包都只是保留對同一對象的引用,而不是複製它。正因爲如此,你走哪條路並不重要。 – dfreeman

1

要得到一點點進一步向你問,這不是關於創建var,而是在您的實例功能也保持arguments陣列。

你的函數可以愉快地在兩者上創建閉包。
通過從函數返回函數,只要不覆蓋這些函數,那些返回的函數(或帶有函數作爲方法的對象)可以訪問任何和所有的varsarguments

關閉的魔力。

+0

這很有趣:發送給包含* arguments *集合的構造函數的每個參數都會保留...對於術語「抱歉」,因爲閉包引用了其中一個參數?或者,參數集合以某種方式減少到只有那些引用它們的元素? –

+1

這對「依賴」領域有點過分。你現在實際上指的是垃圾收集。當一個函數返回時,其內部不再需要,所以整個事情被標記爲垃圾收集。如果仍然有對這些變量/參數/函數之一的生動參考,那麼它不能被收集。這是否意味着這些保存的變量被保存在內存中,其他所有內容都被擦除,或者如果函數的整個範圍在內存中保存,則取決於所討論的JS引擎。 – Norguard

相關問題