2

我想知道如何通过 clojure 在 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 上的这种行为是应该的,但我怎样才能创建真正的私有变量?

4

2 回答 2

3

我知道 javascript 上的这种行为是应该的,但我怎样才能创建真正的私有变量?

你不能,ES5 中没有私有的。如果需要,您可以使用 ES6 私有名称。

您可以使用 ES6 WeakMaps 模拟 ES6 私有名称,该名称可以在 ES5 中填充。这是一个昂贵且丑陋的仿真,这不值得。

于 2012-04-08T22:55:39.093 回答
0

当您需要将私有变量添加到使用 Object.create 创建的一个对象时,您可以这样做:

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

如果你愿意,你甚至可以避免像这样不必要的公共函数 init_private:

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

坏事是你不能用几个电话附加私人成员。好在我认为这种方法非常直观。

此代码已使用 Rhino 1.7 release 3 2013 01 27 测试

于 2013-05-05T18:53:58.280 回答