Скрытие информации при использовании объекта-прототипа - PullRequest
1 голос
/ 21 июня 2011

В нашей кодовой базе я обнаружил, что многие разработчики используют подчеркивание в качестве первой буквы переменной-члена, чтобы препятствовать публичному использованию. Обычно, лучшая практика - просто объявить локальную переменную, которая доступна для методов объекта, но в нашем случае это не представляется возможным, потому что все методы определены в прототипе. Вот пример.

MyContrivedWidget = function(container) {
  this._container = jQuery(container);
}

MyContrivedWidget.prototype = {
  draw: function() {
    var link = jQuery(document.createElement('a'))
      .html('some contrived text')
      .attr('href', '#')
      .appendTo(this._container);
  }
}

У нас есть несколько причин для использования объекта-прототипа, но наиболее убедительным, вероятно, является то, что использование цепочки прототипов позволяет легко наследовать и переопределять методы. Это хорошо для нас, потому что у нас есть несколько продуктов на одной платформе, которые могут захотеть использовать много JavaScript, переопределяя определенные функции.

Итак, мой вопрос: как мы можем получить все преимущества цепочки прототипов, не позволяя переменным, которые должны быть приватными, быть общедоступными?

1 Ответ

1 голос
/ 21 июня 2011

Проще говоря: ECMAscript edition 3 не имеет возможности создавать «приватные» переменные, используя наследование прототипа или цепочку прототипов.

В ES5 немного по-другому. У вас есть такие методы, как .defineProperties() help , которые могут «скрывать» свойства внутри объекта.

Но даже если вы, например, скрываете свойства от перечисления, он все равно сможет получить доступ к ним, если будет знать, что они доступны. Как вы упомянули, единственная реальная конфиденциальность в ECMAland - это закрытие. Проще говоря, используя метод-шаблон, вызывая функцию (-context), которая возвращает объект, который содержит методы в качестве свойств. Эти методы имеют доступ (поскольку его контекст закрывается над родительским контекстом) к объявленным переменным во внешней (родительской) области видимости. Никакой другой объект не может получить доступ к этим переменным после. Это выглядит так:

var Animal = function( args, priv, shared ) {
    shared = shared || { };
    shared.speed = 2;
    shared.legs = 4;
    shared.name = args.name || 'unknown'; 

    priv = priv || {
        run: function() {
            console.log(shared.name, ' is running ', shared.speed, ' meters');
            return this;
        },
        die: function() {
            console.log(shared.name, ': wwuuaarhhhck.. aahahsd sd..aahsd.....');
            return this;
        }
    };

    return priv;
};

var Dog = function( args, priv, secret ) {
    secret = secret || { };

    priv = Animal( args, priv, secret ) || { };

    priv.addSomeMethod = function() { };

    return priv;
};

var bello = Dog({name: 'Bello'});
bello.die(); // "Bello:  wwuuaarhhhck.. aahahsd sd..aahsd....."

Есть несколько замечательных шаблонов, которые расширяют эту идею, которые также предлагают наследование и разделяемые объекты + супер методы. Хорошим началом такого рода программирования по-прежнему остается Дуглас Крокфордс "Javascript: хорошие части".

...