2013-04-02 55 views
2

我試圖理解new操作符。看一看下面的函數:JavaScript中的「新」操作符

var _new = function(fn) { 
    var obj = Object.create(fn.prototype); 
    fn.apply(obj); 
    obj.constructor = fn; // <--- EDIT: unnecessary 
    return obj; 
}; 

可以應用這樣的:

var Test = function(){ 
    this.foo = 1; 
}; 

var instance = _new(Test); 

當然,它可以很容易地擴展到(我只是試圖保持它的參數的任意數簡單)。

它看起來像new關鍵字。那麼,如果有什麼區別? new運算符還有什麼對象?

+0

這有幫助嗎? http://stackoverflow.com/questions/4166616/understanding-the-difference-between-object-create-and-new-somefunction-in-j –

+2

'構造函數'實際上是'fn.prototype'的一個屬性,而不是實例本身。 –

+0

@FelixKling哦,真的嗎?我不知道。這使得代碼更簡單。 – freakish

回答

3

你是對的,這基本上就是new正在做的事情:創建一個新的對象,它繼承自Func.prototype,並且調用Functhis引用這個新對象。

還有就是你的實現雖然略有區別:如果構造(Func)不返回一個對象,this隱含返回。 如果它返回一個對象(任何對象),它將成爲構造函數調用的返回值。

所以更準確的複製將是:

var _new = function(fn) { 
    var obj = Object.create(fn.prototype); 
    var result = fn.apply(obj); 
    return result != null && typeof result === 'object' ? result : obj; 
}; 

就是這樣。如果你願意的話,你可以把它看作句法糖,就像條件運算符一樣。


一些指向所述參考:當使用new,構造的內部[[Construct]]函數被調用。究竟發生了什麼在規範的section 13.2.2中有描述,它和你(和我)寫的功能差不多。

我不完全確定的一點是對象的內部[[Extensible]]屬性設置爲true。我假設你通過Object.create創建的每個對象都是默認可擴展的(如果它的原型是可擴展的)。

+0

哦,哇。這是一個有趣的功能。我一直認爲構造函數返回並不重要。但我從來沒有檢查過。 :)謝謝你的答案! – freakish

+0

不客氣:)增加了一些小小的評論...... –

+0

那麼對於一個可擴展的對象意味着什麼?有沒有不可擴展的物體? – freakish