Закрытые переменные Javascript + Object.create (ссылка на закрывающие переменные)

Мне было интересно, как я мог сделать частные переменные в javascript через clojure. Но все равно их нужно клонировать при использовании 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 предполагается, но как я могу создать истинные частные переменные?

2 ответа

Решение

Я знаю, что такое поведение на javascript предполагается, но как я могу создать истинные частные переменные?

Вы не можете, нет никакого частного в ES5. Вы можете использовать личные имена ES6, если хотите.

Вы можете эмулировать закрытые имена ES6 с помощью слабых карт ES6, которые можно использовать в ES5. Это дорогая и уродливая эмуляция, которая не стоит затрат.

Когда вам нужно добавить приватные переменные только к одному объекту, который был создан с помощью 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 выпуск 3 2013 01 27

Другие вопросы по тегам