Проблемы с «этим» в пространствах имен JavaScript и слушателях событий - PullRequest
2 голосов
/ 31 мая 2011

Прежде всего, я пытаюсь использовать поддельные пространства имен в моей JavaScript-программе, например:

// Ish.Com namespace declaration
var Ish = Ish || {};
Ish.Com = Ish.Com || {};

// begin Ish.Com.View namespace
Ish.Com.View = new function() {
  var privateVariable;

  this.publicFunction = function() {
    this.publicFunction2()
  };

  this.publicFunction2 = function() { ... };
};

Я не без ума от использования this для вызова других функций, но до недавнего времениСработало.Однако я добавил слушателей событий к некоторым элементам, и они интерпретируют this как целевой объект.

Я знаю, что могу использовать полное пространство имен вместо this для вызова функций внутри моих слушателей.(Ish.Com.View.publicFunction2()), но слушатели часто вызывают одну функцию, которая вызывает другую, и другую.Мне нужно было бы использовать все пространство имен почти при каждом вызове функции.

Как мне заставить пространства имен работать хорошо с прослушивателями событий? Мне также был бы интересен лучший способреализация пространств имен, поскольку использование this.publicFunction2() неуклюже.

Я очень заинтересован в передовых практиках и изучении того, как написать хорошо спроектированное приложение на JavaScript.Однако о фреймворках не может быть и речи, пока я не получу более глубокое понимание JavaScript.

Ответы [ 3 ]

4 голосов
/ 31 мая 2011

Похоже, что я отвечал на каждый вопрос сегодня утром одинаково: -)

Вы можете использовать ".bind ()":

   var eventHandler = yourObject.someFunction.bind(yourObject);

Это гарантирует, что this будет ссылаться на "yourObject" всякий раз, когда "eventHandler" вызывается чем-либо.

Функция «bind ()» есть в объекте Function.prototype в новых браузерах. Документы Mozilla включают надежную реализацию "bind ()", которую можно использовать для исправления старых браузеров.

Что делает «bind ()», так это возвращает вам новую функцию, которая явно организует привязку this в соответствии с вашими условиями. Вы также можете передать аргументы для передачи, если хотите. Альтернативой использованию «bind ()» является завершение вызова функции в вашей собственной анонимной функции:

  var eventHandler = function() { yourObject.someFunction(); };
0 голосов
/ 31 мая 2011

Это вызвано переменным контекстом и закрытием.« this » всегда относится к текущему объекту.Функция события сама является объектом, и « this » относится к этому объекту.Если вам нужно обратиться к родительскому объекту, вы можете использовать связывание, как описано ранее, или установить родительскую переменную " this " в переменную и использовать ее в своей функции события.

// Ish.Com namespace declaration
var Ish = Ish || {};
Ish.Com = Ish.Com || {};
// begin Ish.Com.View namespace
Ish.Com.View = new function() {
  var privateVariable, thisObj=this;
  this.publicFunction = function() {
    thisObj.publicFunction2()
  };
  this.publicFunction2 = function() { ... };
};
0 голосов
/ 31 мая 2011

Я не знаю, полностью ли я понял ваш вопрос.Подойдет ли это вам?

var obj = new function() {
    var scope = this;

    this.fun1 = function() {
        return scope.fun2();
    }

    this.fun2 = function() {
        //do sth
    }
};
...