2009-09-02 6 views
11

Я пытаюсь получить доступ к переменным-членам класса прототипа в JavaScript в обработчике событий - то, что я обычно использовал для этого ключевого слова для (или «that» [копия этого] в случае обработчиков событий). Излишне говорить, что у меня проблемы.«this» ключевое слово в методах событий при использовании объекта прототипа JavaScript

Возьмем, к примеру, этот HTML фрагмент:

<a id="myLink" href="#">My Link</a> 

И этот JavaScript код:

function MyClass() 
{ 
    this.field = "value" 
    this.link = document.getElementById("myLink"); 
    this.link.onclick = this.EventMethod; 
} 

MyClass.prototype.NormalMethod = function() 
{ 
    alert(this.field); 
} 

MyClass.prototype.EventMethod = function(e) 
{ 
    alert(this.field); 
} 

Инстанцирование объект MyClass и вызов NormalMethod работает точно так же, как я ожидать, что это (предупреждение говоря " value "), но нажатие ссылки приводит к неопределенному значению, потому что ключевое слово this это ссылка на объект назначения (элемент HTML anchor()).

Я новичок в прототип JavaScript стиль, но в прошлом, с закрытием, я просто сделал копию «это» в конструкторе:

var that = this; 

И тогда я мог бы получить доступ к членам переменные в методах событий через объект «тот». Это не похоже на прототип кода. Есть ли другой способ достичь этого?

Спасибо.

+0

Вы со ссылкой на библиотеку Prototype или, вернее, прямо JavaScript прототипов классов? –

+3

Отвечая на три года позже :) Но для потомков: я имел в виду прямые прототипы классов JavaScript. – Michael

+0

Возможный дубликат [Как получить доступ к правильному 'this'/context внутри обратного вызова?] (Http://stackoverflow.com/q/20279484/1048572)? – Bergi

ответ

9

Ваше "that=this" закрытие идиомы по-прежнему применимо:

function MyClass() 
{ 
    ... 

    var that = this; 
    this.link.onclick = function() { 
     return that.EventMethod.apply(that, arguments); 

     // that.EventMethod() works too here, however 
     // the above ensures that the function closure 
     // operates exactly as EventMethod itself does. 

    }; 
} 
5

Вы должны попробовать

this.link.onclick = this.EventMethod.bind(this); 
13

Понадобится:

this.link.onclick = this.EventMethod.bind(this); 

... 'связывают' является частью прототипа, и возвращает функцию, которая правильно называет ваш метод «этим».

+0

Как «onclick» получает доступ к интерфейсу событий? – Karl

+0

@Karl Посредством «доступа к интерфейсу событий» вы имеете в виду «получить объект события в качестве аргумента»? Метод 'bind' ** возвращает функцию ** (с фиксированным' this'), поэтому 'onclick = this.EventMethod' в основном совпадает с' onclick = this.EventMethod.bind (this) '.В обоих случаях вы сохраняете функцию в свойстве 'onclick'; они идентичны с точки зрения того, как обрабатываются их аргументы. Если ваш вопрос в основном связан с тем, как аргументы передаются в функции слушателя, это совсем другой вопрос, чем то, что здесь задается, и вы должны задать новый вопрос. – apsillers

0

Как указано выше, использование связывания, являющегося частью библиотеки Prototype, является чистым способом решения этой проблемы. Этот вопрос является дубликатом другого SO вопроса, который отвечал здесь с реализацией методы связывания без включения всей библиотеки прототипа:

https://stackoverflow.com/a/2025839/1180286

+0

Этот вопрос использует JQuery. Я бы предпочел, чтобы в качестве стандартного вопроса был задан вопрос/ответ на чистый вопрос. –