2012-06-28 70 views
4

代碼可以在這裏玩 - http://jsfiddle.net/dsjbirch/zgweW/14/爲什麼Object.create使我的私有變量是靜態的?

這基本上是一個直接複製和粘貼crockfords私人變量的解釋。

我已添加Object.create()和一點追蹤。

爲什麼第二個對象會共享第一個對象的私有成員?如何避免這種情況,但繼續使用Object.create()

function Container(param) { 

    function dec() { 
     if (secret > 0) { 
      secret -= 1; 
      return true; 
     } else { 
      return false; 
     } 
    } 

    this.member = param; 
    var secret = 3; 
    var that = this; 

    this.service = function() { 
     return dec() ? that.member : null; 
    }; 
} 

var first = new Container("private"); 

var second = Object.create(first); 

document.write(first.service() + "<br/>"); 
document.write(first.service() + "<br/>"); 
document.write(first.service() + "<br/>"); 
document.write(first.service() + "<br/>"); 

document.write(second.service() + "<br/>"); 
document.write(second.service() + "<br/>"); 
document.write(second.service() + "<br/>"); 
document.write(second.service() + "<br/>"); 

http://jsfiddle.net/dsjbirch/zgweW/14/

我希望看到

private 
private 
private 
null 

private 
private 
private 
null 

但實際工作中的第二個對象的輸出爲全空。

private 
private 
private 
null 

null 
null 
null 
null 

我得出結論:second是爲此共享first對象的secret成員。

+0

+1 http://jsfiddle.net/ –

+0

後,我感到困惑你的期望是什麼VS,你看到的調用構造函數在jsFiddle上。你能否提供一些你不明白的細節? –

+0

-1爲jsfiddle.net(@Ashish Gupta)。爲什麼不在這裏粘貼代碼,以及結果? – Bergi

回答

1

它們不是靜態的,它們是「第一個」對象的實例成員。您從未爲「第二個」對象創建任何新的實例成員,因爲您從未調用過其構造函數。相反,您將「second」的原型設置爲「first」,這意味着每當「second」訪問缺失的屬性時,您將從「first」獲得值。

可以使用的Object.create的東西,如

Container.call(second, param); 
1

Object.create()將不會運行構造。但在你的例子中,構造函數就是你的私人魔法發生的地方。相反,Object.create()只是簡單地創建一個新對象,並將屬性複製到它。

那麼會發生什麼呢是構造函數創建一個範圍,這是共享的,因爲在該範圍內創建的函數得到複製。當實例被克隆時,訪問該範圍也是如此。

+1

它不復制屬性,它設置了原型鏈。 – Bergi

+1

是的,我猜這是更準確的,但它仍然使特權功能可用於創建的對象。這是重要的一點。 –

相關問題