Объем обратного вызова JavaScript

Как и предполагаемые комментарии, решение заключается в использовании вложенных пространств / строк.

<div class="container">
    <div class="row">
        <div class="span4">1</div>
        <div class="span8">
            <div class="row">
                <div class="span4">2</div>
                <div class="span4">3</div>
            </div>
            <div class="row">
                <div class="span4">4</div>
                <div class="span4">5</div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="span4">6</div>
        <div class="span4">7</div>
        <div class="span4">8</div>
    </div>
</div>
58
задан Chris MacDonald 8 October 2008 в 14:56
поделиться

6 ответов

(извлек некоторое объяснение, которое было скрыто в комментариях в другом ответе)

проблема заключается в следующей строке:

this.dom.addEventListener("click", self.onclick, false);

Здесь, Вы передаете функциональный объект, который будет использоваться в качестве обратного вызова. Когда триггер события, функция вызвана, но теперь это не имеет никакой связи ни с каким объектом (это).

проблема может быть решена путем обертывания функции (с, он - ссылка на объект) в закрытии следующим образом:

this.dom.addEventListener(
  "click",
  function(event) {self.onclick(event)},
  false);

, Так как переменная сам была присвоена это , когда закрытие было создано, функция закрытия будет помнить значение сам переменная, когда это звонило в более позднее время.

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

function bind(scope, fn) {
    return function () {
        fn.apply(scope, arguments);
    };
}

обновленный код был бы тогда похож:

this.dom.addEventListener("click", bind(this, this.onclick), false);
<час>

Function.prototype.bind часть ECMAScript 5 и обеспечивает ту же функциональность. Таким образом, можно сделать:

this.dom.addEventListener("click", this.onclick.bind(this), false);

Для браузеров, которые еще не поддерживают ES5, , MDN обеспечивает следующий контейнер :

if (!Function.prototype.bind) {  
  Function.prototype.bind = function (oThis) {  
    if (typeof this !== "function") {  
      // closest thing possible to the ECMAScript 5 internal IsCallable function  
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");  
    }  

    var aArgs = Array.prototype.slice.call(arguments, 1),   
        fToBind = this,   
        fNOP = function () {},  
        fBound = function () {  
          return fToBind.apply(this instanceof fNOP  
                                 ? this  
                                 : oThis || window,  
                               aArgs.concat(Array.prototype.slice.call(arguments)));  
        };  

    fNOP.prototype = this.prototype;  
    fBound.prototype = new fNOP();  

    return fBound;  
  };  
} 
81
ответ дан Felix Kling 7 November 2019 в 15:28
поделиться
this.dom.addEventListener("click", function(event) {
    self.onclick(event)
}, false);
15
ответ дан Yi Jiang 7 November 2019 в 15:28
поделиться

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

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

-3
ответ дан Javier 7 November 2019 в 15:28
поделиться

Объяснение состоит в том, что self.onclick не означает то, что Вы думаете, что это означает в JavaScript. Это на самом деле означает эти onclick функция в прототипе объекта self (всегда не ссылаясь self самого).

JavaScript только имеет функции и никаких делегатов как C#, таким образом, не возможно передать метод И объект, к этому нужно относиться как обратный вызов.

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

var obj = ...;
function callback(){ return obj.method() };
something.bind(callback);
2
ответ дан Vincent Robert 7 November 2019 в 15:28
поделиться

Я написал этот плагин ...

Думаю, он будет полезен

jquery.callback

1
ответ дан 24 November 2019 в 18:56
поделиться

Хорошее объяснение проблемы (у меня были проблемы с пониманием решений, описанных до сих пор) доступно здесь .

2
ответ дан 24 November 2019 в 18:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: