Javascript: как получить доступ к открытым переменным-членам при создании объекта с немедленным вызовом - PullRequest
0 голосов
/ 21 октября 2011

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

var myObj = (function () {
  // Private member variables
  var privateX;

  function setPropX (value) {
    privateX = value;
  }

  function getPropX () {
    return privateX;
  }

  function init() {
    privateX = "Initial value privateX";
  }

  init();

  // Public API
  return {
    // Methods
    "setPropX": setPropX,
    "getPropX": getPropX
  };
}());

После этого я могу нормально работать с объектом, используя публичный API, но мои закрытые члены правильно скрыты:

myObj.setPropX("Hello world");
alert(myObj.getPropX());           // --> Hello world
alert(myObj.privateX);             // --> Undefined

Теперь на мой вопрос:

Можно ли добавить к объекту публичные свойства, к которым может обращаться как вызывающий объект, так и из моего кода? Затем они будут использоваться так:

myObj.publicY = "ABC";
myObj.sayPublicY();           // Should alert --> ABC

Я пытался сделать это так:

var myObj = (function () {
  // Private member variables
  var self = this;
  var privateX;

  function setPropX (value) {
    privateX = value;
  }

  function getPropX () {
    return privateX;
  }

  function sayPublicY () {
    alert(self.publicY);
  }

  function init() {
    privateX = "Initial value privateX";
    self.publicY = "Initial value publicY";
  }

  init();

  // Public API
  return {
    // Methods
    "setPropX": setPropX,
    "getPropX": getPropX,
    "sayPublicY": sayPublicY
  };
}());

Я думал, что это будет работать, но это не так. Ссылка self, сохраненная в замыкании, ссылается на объект window. Почему это не ссылка myObj?

Я, должно быть, упускаю что-то очевидное, но я не смог найти ничего в Google или SO.

Как правильно это сделать?

EDIT: добавлены детали метода init (), который все еще не работает

1 Ответ

2 голосов
/ 21 октября 2011

Потому что в вашем закрытии this (var self = this;) равно window, а не созданному вами экземпляру. Это объявление self бесполезно; всегда равно window и должно быть удалено (и не использовано).

Разрешение this задерживается до времени выполнения, однако, поскольку вы специально используете self вместо this, вы всегда используете window. Измените self на this внутри sayPublicY, и оно будет работать.

Использование функции init с использованием этой формы построения недопустимо. constructor в этом коде состоит из следующих нескольких строк:

return {
  // Methods
  "setPropX": setPropX,
  "getPropX": getPropX,
  "sayPublicY": sayPublicY
};

Вплоть до тех нескольких строк у вас нет экземпляра myObj. У вас просто есть определения и объявления частных переменных / методов, которые могут быть добавлены к объекту myObj. Оператор return создает ваш myObj и присваивает ему методы setPropX, getPropX и sayPublicY. Здесь вы также должны добавить свой атрибут publicY:

return {
  // Methods
  "setPropX": setPropX,
  "getPropX": getPropX,
  "sayPublicY": sayPublicY,
  "publicY": "Initial Value of Public Y"
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...