это и передача функции в качестве параметра в Javascript - PullRequest
3 голосов
/ 22 января 2012

У меня есть следующие объекты Javascript:

function Alfa() {
  this.status='';
  this.setStatus = function(value) {
    this.status=value
  }
}

function Beta() {
  this.setSomething = function(setter) {
    setter('Something');
  }
}

А чем исполнение:

alf=new Alfa();
alf.setStatus('foo');

Это прекрасно работает, если вы посмотрите на значения alf , статус будет установлен в 'foo', но:

bet=new Beta();
bet.setSomething(a.setStatus);

Я ожидал, что bet выполнит setStatus функцию alf и установит значение status в 'что-то', однако Этого не происходит. setStatus из alf выполняется, но это указывает не на alf экземпляр, а на Window , поэтому состояние свойства устанавливается на Окно не для alf .

Каков правильный подход для получения желаемой функциональности?

Это, конечно, упрощенная реализация, в реальной жизни я хочу передать эти функции alf обработчикам событий, поэтому я не могу изменить реализацию Beta , например:

$('xxx').click(alf.setStatus)

Ответы [ 4 ]

4 голосов
/ 22 января 2012

Функции JavaScript не связаны.Это означает, что this определяется тем, как он вызывается, а не тем, как он был определен.Поскольку вы вызываете метод из bet, то this равно bet

Чтобы обойти это, вам нужно создать связанную функцию , которая создает стабильную this независимо от того, как вызывается функция.

Если вы используете ES5-совместимый интерпретатор JavaScript, вы можете использовать: Function.bind

alf.setStatus.bind(alf)

Или, если у вас нет, есть несколько шайб es5, которые обеспечивают этофункциональность в старых переводчиков.На самом деле, один из них указан в ссылке mdn для bind.JQuery имеет версию с именем $.proxy

. Простая реализация заключается в том, что вам нужна функция, которая принимает функцию и область видимости.И затем вызывает ваш метод именно в этой области, а не использует это.Что-то вроде.

function bind(func,o) { return function() { func.call(o); } }
1 голос
/ 22 января 2012
function Alfa() {
    this.status='';
    this.setStatus = function(value) {
        this.status=value
    }
}
function Beta() {
    this.status='';
    this.setSomething = function(setter) {
        setter.call(this,'Something');
     }
}
1 голос
/ 22 января 2012

Изменение setter('Something'); на setter.call(this, 'Something'); будет работать.

1 голос
/ 22 января 2012

Функции в JavaScript не имеют привязанного к ним контекста, например, связанные методы в Python.Поэтому вы можете вызывать функции setStatus с контекстом, например:

bet.setSomething(function(value) {
    a.setStatus.call(a, value);
});

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...