Разделение при использовании анонимных функций в стороннем javascript (FB) - PullRequest
2 голосов
/ 12 мая 2011

Я использую модель наблюдателя FB.Event.subscribe (), чтобы выяснить, когда пользователь входит в систему. Этот метод принимает два аргумента, строку, содержащую объект для наблюдения, и функцию обратного вызова.

Я слежу за несколькими событиями, которые обрабатывают событие одинаково, поэтому я настроил функцию обратного вызова как предопределенный метод и передал это в FB.Event.subscribe () следующим образом:

Controller.prototype.go = function() {
    FB.Event.subscribe('auth.login', this.fbHandleStatusChange);
    FB.Event.subscribe('auth.logout', this.fbHandleStatusChange);
}

Controller.prototype.fbHandleStatusChange = function(response) {
    // Doesn't work
    this.otherFunction();
}

Controller.prototype.otherFunction = function() {
    alert('hello');
}

К сожалению, это означает, что я теряю доступ к 'this' в рамках fbHandleStatusChange, очевидно, я не хочу начинать кодировать ссылки на конкретные версии Controller!

Я предполагаю, что неправильно передаю функцию?

Спасибо.

1 Ответ

3 голосов
/ 12 мая 2011

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

Проверьте документы FB.Event.subscribe, чтобы увидеть, предлагает ли он способ сказать, какой "контекст" использовать для вызова функции обработчика события.Это может предложить способ сделать это.(Обычно это context или thisArg параметр.)

Если нет, вы можете легко решить проблему с помощью замыкания:

Controller.prototype.go = function() {
    var self = this;

    FB.Event.subscribe('auth.login', handleChange);
    FB.Event.subscribe('auth.logout', handleChange);
    function handleChange() {
        return self.fbHandleStatusChange();
    }
}

, который захватывает копию this в переменную с именем self, которая используется функцией handleChange (которая является замыканием над областью, содержащей переменную self) для вызова вашей функции с правильным контекстом.Подробнее о крышках здесь: Крышки не сложны Подробнее о this здесь: Вы должны помнить this

С другой стороны, действительно ли у вас будет несколько экземпляров Controller?Люди, приходящие на JavaScript из языков классов, склонны без необходимости использовать функции конструктора (грубый аналог «класса»).Это правильный выбор, если вам нужно иметь более одного экземпляра объекта, но если вы когда-либо будете иметь только один Controller объект на странице, тогда используйте функцию конструктора и возитесь с this является излишним.

Если вам не нужно несколько независимых Controller экземпляров, то:

var controllerObject = (function() {
    var inst = {};

    inst.go = go; // Make `go` a publicly-accessible function of the object
    function go() {
        FB.Event.subscribe('auth.login', fbHandleStatusChange);
        FB.Event.subscribe('auth.logout', fbHandleStatusChange);
    }

    // This is private to us, so we don't expose it as a property on the object
    function fbHandleStatusChange(response) {
        // Doesn't work
        otherFunction();
    }

    // This is also private to us
    function otherFunction() {
        alert('hello');
    }

    return inst;
})();

Это создает частную область через внешний анонимфункция, и в этой области создает экземпляр (inst), который мы затем возвращаем и называем controllerObject.controllerObject в вышеприведенном имеет только одно свойство, функция go.Все остальные наши функции по-настоящему приватны.(Я также взял на себя смелость гарантировать, что функции имеют имен , потому что помогает вашим инструментам помочь вам .)

Обратите внимание, что на самом деле мы необращайтесь к inst в любом месте наших вызовов функций, потому что все они локальны по отношению к области закрытия.Мы можем даже иметь личные данные, имея другие var s во внешнем закрытии.

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