Приватность в JavaScript - PullRequest
       29

Приватность в JavaScript

4 голосов
/ 28 февраля 2011

Я знаю, что вы можете достичь чего-то такого, как "приватность" в JavaScript, используя замыкания и функции немедленного вызова.

Но что, если мне нужно полнофункциональное прототипирование? Я просто не знаю, как иметь закрытых членов в прототипе объекта. Если я использую привилегированные методы, у меня могут быть частные переменные и публичные методы, но я теряю возможность создания прототипов.

Дуглас Крокфорд «запрещает» использование висячего (подчеркивание перед идентификатором указывает, что оно не является частью открытого интерфейса).

Но разве это плохо? Поскольку нет возможности сделать его по-настоящему приватным.

Что вы думаете об этом? Как вы справляетесь с этим?

Ответы [ 3 ]

5 голосов
/ 28 февраля 2011

Во-первых, вы действительно не потеряете эффект прототипирования при использовании шаблона функционального наследования.Я просто предполагаю, что вы говорите о хороших частях , Крокфорд также представил довольно простой и эффективный способ иметь общих переменных для этого шаблона.Что в основном выглядит следующим образом:

var Human = (function(my, priv) {
    var my   = my || {},
        priv = priv || {};

    my.privatedata = "foobar";

    priv.walk = function() {
        console.log('walking');
        return priv;
    };
    priv.talk = function() {
        console.log('blah blah');
        return priv;
    };

    return priv;
}());

var Andy = (function(my, priv) {
    var my   = my || {},
        priv = Human(my, priv);

    priv.SpecialAndyThing = function() {
        console.log('bloggin at typeofnan.com');
        return priv;
    };

    return priv;
}());

var myAndy = Andy();
myAndy.talk().SpecialAndyThing();

Вы можете даже просто расширить эту технику, чтобы иметь некоторые методы super .Использование загадочных соглашений о переменных, таких как подчеркивание или что-то еще, является плохой практикой в ​​целом.Это сбивает с толку, поскольку никто просто не знает, что там происходит (возможно, этот аргумент не сработает, если вы единственный, кто использует кодовую базу).


Тем не менее, в ECMAscript Edition 5 есть некоторые полезные свойства, чтобы иметь больше "приватности""члены цепочки прототипов .Одним из важных методов для этого является .defineProperty, где вы можете определить свойство, которое не «поверхностно» до конца.Будет выглядеть так:

var Human = {};

Object.defineProperty(Human, 'privateStuff', {
    value:      'secret',
    enumerable: false
});

Теперь свойство privateStuff не отображается для объекта, который наследуется от цепочки прототипов Human.В любом случае, для этого требуется Javascript 1.8.5, и пока он доступен только в самых современных браузерах.См https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty

1 голос
/ 12 апреля 2011

Вот пример того, как разрешить прототипным функциям обращаться к закрытым переменным во всех браузерах:

var Book = (function() {
  var $ = {};

  var Book = function(newFirst, newLast) {
    // Private variables stored in an object literal.
    var _ = {
      author_first : newFirst,
      author_last : newLast
    };

    // Public privileged method for accessing private variables.
    this._ = function(key) {
      if(key === $)
        return _;
      throw new Error("The _() function must be called internally.");
    };
  };

  // Public accessor method.
  Book.prototype.getAuthor = function() {
    var _ = this._($);
    return _.author_first + " " + _.author_last;
  };

  return Book;
})();

var bookA = new Book("Chris", "West"),
    bookB = new Book("Douglas", "Crockford");
alert(bookA.getAuthor());
alert(bookB.getAuthor());

Это так же, как я реализовал класс Color в jPaq .

1 голос
/ 28 февраля 2011

Вас могут заинтересовать Шаблоны проектирования JavaScript . Здесь также обсуждается Шаблон модуля .

...