Подтвердить что ты не робот

Доступ к свойству объекта из вызова прослушивателя событий в Javascript

Ниже я создаю объект в Javascript. Внутри конструктора я настраиваю прослушиватель событий. Проблема в том, что при запуске события this.prop не может быть найден, а undefined распечатывается. Как я могу это решить?

   var someObj = function someObj(){
       this.prop = 33;
        this.mouseMoving = function() { console.log(this.prop);}

        document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);

 }
4b9b3361

Ответ 1

При вызове обработчика событий "this" больше не ссылается на объект "someObj". Вам нужно записать "this" в локальную переменную, которую будет захватывать функция mouseMoving.

var someObj = function someObj(){
    this.prop = 33;
    var self = this;
    this.mouseMoving = function() { console.log(self.prop);}

    document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}

Я предполагаю, что "someObj - это конструктор, т.е. предназначенный для вызова с помощью new someObj(), иначе "this" будет глобальной областью.

Ключевое слово "this" может сбивать с толку в JavaScript, потому что оно не работает так же, как на других языках. Главное помнить, что он связан с вызывающим объектом , когда функция вызывается, а не при создании функции.

Ответ 2

Для этой цели предназначен встроенный в Javascript Function.prototype.bind().
Например:

var someObj = function someObj(){
       this.prop = 33;
        this.mouseMoving = function() { console.log(this.prop);}

        document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);

 }

Подробнее о методе связывания здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Иными словами, вы должны передать ссылку на объект someObj элементу и использовать эту ссылку в строке:

console.log(this.referenceToObject.prop); //this references the DOM element in an event.

Ответ 3

Из раздела 4.3 JavaScript: хорошие части Дуглас Крокфорд:

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

Крокфорд продолжает объяснять привязку 'this' в каждом из этих шаблонов следующим образом:

Шаблон вызова метода: Когда функция хранится как свойство объекта, мы называем ее методом. Когда метод вызывается, это связано с этим объектом.

Шаблон вызова функции: Когда функция вызывается с этим шаблоном, это связано с глобальным объектом. Это было ошибкой в ​​оформлении языка.

Шаблон вызова конструктора: Если с новым префиксом вызывается функция, тогда будет создан новый объект со скрытой ссылкой на значение элемента-прототипа функции, и это будет связано с этим новым объектом.

Шаблон Apply Invocation: Метод apply позволяет нам построить массив аргументов для использования функции. Это также позволяет нам выбрать значение этого. Метод apply принимает два параметра. Первое - это значение, которое должно быть связано с этим. Второй - это массив параметров.

Ответ 4

Во-первых, вам нужно понять, как работает 'this' в JavaScript. 'this' ключевое слово не ведет себя так, как оно ведет себя на других языках, таких как С# или JAVA. Читайте следующее сообщение, чтобы понять больше,

Каково обоснование поведения ключевого слова 'this' в JavaScript?

Как только вы поймете это, как изложил Мэттью в своем коде, вы можете сохранить ссылку на 'this' и использовать эту ссылку в функции mouseMoving.

Хотя в целом я посоветую вам использовать инфраструктуру JavaScript (например, jQuery, YUI, MooTools), которая позаботится об этих проблемах для вас. Например. В Internet Explorer вы используете addEvent для присоединения события, а не addEventListenr.

Ответ 5

Вы можете использовать переменную с именем "me", чтобы избежать конфликта с глобальной переменной JavaScript "self": ​​

function someObj() {
  var me = this;
  this.prop = 33;

  this.mouseMoving = function() {
    alert(me.prop);
  }

  document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}

Ответ 6

У вас есть опечатки в объявлении функции.

Ваша переменная prop также определяется как "общедоступный" или "видимый" член (с помощью this.prop), поэтому вы вынуждаете вас хранить ссылку этого из внешней функции (которая на самом деле является ссылкой на объект экземпляр), как член "private" функции (с помощью var), чтобы получить доступ к экземпляру созданного объекта и прочитать "открытый" элемент поддержки.

У вас есть несколько альтернатив для перезаписи этого кода:

function someObj (){
    var self = this;
    this.prop = 33;
    this.mouseMoving = function() { alert(self.prop);} // You access the current
                                                       // instance, stored in *self*
                                                       // since *this*, inside the 
                                                       // function, is in another 
                                                       // context.
    //...
}

var mySomeObj = new someObj(); // Object instantiation

Или вы могли:

function someObj (){
    var prop = 33;
    this.mouseMoving = function() { alert(prop);} 

    //...
}
var mySomeObj = new someObj(); // Object instantiation

Переменные, объявленные с помощью var, доступны для функций, объявленных внутри основной функции конструктора, эта функция называется Closures.