Есть ли в любом случае, чтобы экземпляры совместно использовали одну и ту же функцию, но в то же время имели частные переменные? - PullRequest
6 голосов
/ 14 мая 2011

У меня есть этот кусок кода:

var Human=function(name){
  this._name=name;
};
Human.prototype.Shout=function(){
  alert(this._name);
};

var tom=new Human("tom");
var john=new Human("john");
alert(tom.Shout===john.Shout);

Прямо сейчас ._name не является "личным". Я хочу сделать ._name "приватным", но в то же время я не хочу создавать дополнительные функции для каждого экземпляра человека (другими словами, tom.Shout Должен быть === для john.Shout), потому что создание дополнительных функций для каждый экземпляр просто хорош .. ненужен (хорошо оффтоп - мы можем обсудить это в другой теме)

Я пришел к выводу, что то, чего я пытаюсь достичь (имея ._name быть «приватным» и в то же время иметь tom.Shout===john.Shout), невозможно.

Но я просто хочу быть уверен на 200%, прежде чем делать какие-либо выводы.

(я приветствую любые взломы, если выполняются требования, т. Е. Не требуется создавать дополнительные функции для каждого экземпляра)

Если нам нужно создать дополнительные функции для определения объема, это нормально, но это число должно быть фиксированным, и это число не должно увеличиваться с каждым дополнительным экземпляром Человека.

Ответы [ 3 ]

3 голосов
/ 14 мая 2011

Обновление

Вы ищете @name, который является переменной экземпляра.Молитесь, чтобы это было в es.next, но у нас его пока нет.Может быть, через два года.

Если вы заботитесь о чистом API, вот ваше решение:

function Class(foo) {
    Class.priv(this).foo = foo;
}

Class.priv = (function() {
    var cache = [],
        uid = 1;

    return function(obj) {
        if (!this.__id) {
            this.__id = uid;
            cache[uid++] = {};
        }
        return cache[this.__id];
    };

}());

Class.prototype.bar = function() {
    console.log(Class.priv(this).foo);
}

Сохраните все данные в кэше как функцию конструктора.Никакие данные не загромождены на объекте.

Оригинал

Однако не существует такой вещи, как "частный".

Все, что вы можете сделать, это создатьлокальная переменная внутри функции.

Функция конструктора

var Human = function(name) {
    // local variable.
    var _name = name;
}

Имеет локальную переменную, которая по определению локальной не может использоваться вне функции конструктора.

Это означает, что вы не можете получить к нему доступ во внешнем коде, как в прототипе.

Однако вы можете сделать его доступным только для чтения, используя ES5

var Human = function(name) {
    Object.defineProperty(this, "name", { value: name });
}

Если выможет действительно достичь того, что вы просите, вы бы сделали огромный прорыв в JS.Я пытался делать это в течение многих часов.

Другой шаблон будет выглядеть так:

var Human = function(name) {
   this.name = name;

   return {
       Shout: this.Shout.bind(this)
   };
}

Human.prototype.Shout = function() {
   console.log(this.name);
}

Это накладные расходы на вызов .bind и создание нового объекта для каждого экземпляра.хотя.

1 голос
/ 14 мая 2011

Прочитал вопрос, не понял, потому что this._name просто не приватный, поэтому вопрос немного странный.Вот как в моем тесте методы-прототипы добавляются один раз и доступны для всех экземпляров.Я повторяю: this._name здесь не приватно.Если вы добавляете локальную переменную и хотите получить к ней доступ через замыкание в методе-прототипе, вызов значения локальной переменной приведет к одинаковому значению для всех экземпляров.

В любом случае, с помощью этой функции конструктора функцияМетоды получения и крика this._name добавляются в цепочку прототипов один раз и, таким образом, доступны для всех экземпляров человека.

function Human(name) {
    if (!(this instanceof Human)){
        return new Human(name);
    }
    this._name = name;

    if (!Human.prototype.Name){
         Human.prototype.Name = function(val){
            if (val){
               this._name = val;
               return this;
            }
            return this._name;
          };
          Human.prototype.shout = function(){
              alert(this._name);
          }
    }
}
1 голос
/ 14 мая 2011

как насчет этого?

    var Human = function (name) {
        var _name = name;

        this.getName = function () {
            return _name;
        }
    };
    Human.prototype.Shout = function () {
        alert(this.getName());
    };

    var tom = new Human("tom");
    var john = new Human("john");

    tom.Shout(); // tom
    john.Shout(); // john
    alert(tom.Shout === john.Shout); // true

РЕДАКТИРОВАТЬ: первый создает другую функцию для свойства GET, это невозможно без создания дополнительных функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...