2012-04-08 38 views
2

我想知道如何通過clojure在javascript中創建私有變量。但是在使用Object.create時仍然會克隆它們。Javascript私有變量+ Object.create(引用閉包變量)

var point = {}; 
(function(){ 
    var x, y; 
    x = 0; 
    y = 0; 
Object.defineProperties(point, { 
    "x": { 
     set: function (value) { 
     x = value; 
     }, 
     get: function() { 
     return x; 
     } 
    }, 
    "y": { 
     set: function (value) { 
     y = value; 
     }, 
     get: function() { 
     return y; 
     } 
    } 
    }); 
}()); 

var p1 = Object.create(point); 
p1.x = 100; 
console.log(p1.x); // = 100 
var p2 = Object.create(point); 
p2.x = 200; 
console.log(p2.x); //= 200 
console.log(p1.x); //= 200 

我得到這個技術從http://ejohn.org/blog/ecmascript-5-objects-and-properties/但它有這個限制,封閉變量是所有的對象是相同的。我知道這在javascript上的行爲是假設,但我怎樣才能創建真正的私有變量?

+0

這個代碼看起來自動生成測試,是由Clojure的代碼產生的呢? – Raynos 2012-04-08 22:38:43

+0

不是這不是你爲什麼認爲它看起來自動生成? – automaticoo 2012-04-08 22:45:57

+0

作爲沒有私有變量的替代方案可以是http://jsfiddle.net/heera/G9E9m/ – 2012-04-08 23:34:29

回答

3

我知道這在javascript上的行爲是假設,但我怎麼能創建真正的私有變量?

你不能,在ES5中沒有私有。如果需要,您可以使用ES6私有名稱。

您可以使用ES6 WeakMaps模擬ES6私有名稱,這些名稱可以在ES5中進行擦除。這是一個昂貴和醜陋的模擬,這是不值得的成本。如果你願意,你甚至可以避開這樣的不必要的公共職能init_private

var parent = { x: 0 } 
var son = Object.create(parent) 
son.init_private = function() 
{ 
    var private = 0; 
    this.print_and_increment_private = function()  
    { 
     print(private++); 
    } 
} 
son.init_private() 
// now we can reach parent.x, son.x, son.print_and_increment_private but not son.private 

+0

我認爲,作爲沒有私有變量的替代方案可以是http://jsfiddle.net/heera/G9E9m/ – 2012-04-08 23:37:01

0

當你需要私有變量增加,將其用的Object.create創建只有一個對象,你可以讓這個

(function()                                                  
{                                                    
    var private = 0; 
    this.print_and_increment = function() 
    { 
     print(private++); 
    } 
} 
).call(son) 

壞的事情是,你不能追加私有成員多次調用。好的是,我認爲這種方法非常直觀。

此代碼是犀牛1.7版本3 2013 01 27