2012-04-08 37 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