Сохранение данных, полученных от анонимной функции, в объекте класса

#javascript #facebook #asynchronous #anonymous-function

#javascript #Facebook #асинхронный #anonymous-функция

Вопрос:

Я пытаюсь сохранить данные, которые я получаю от вызова Facebook API, в свойстве класса.

Мой конструктор:

 function Foo() {
    this.bar = {
        likes: 0
    };
}
  

Способ обновления объекта:

 Foo.prototype.update = function() {
    FB.api('/me/likes', function (response) { 
        // this.bar['likes'] is out of the scope
    });

}


var foo = new Foo();
foo.update();
  

Возможно ли это или я должен просто попытаться выполнить синхронный вызов вместо этого?
Я не уверен, поддерживает ли Facebook API это.

Спасибо

Комментарии:

1. Вы сохраняете данные в свойстве объекта, а не класса. JavaScript является прототипом языка и не имеет классов, подобных классическому языку. В JavaScript функции являются объектами первого класса, Foo это объект. Использование заглавной буквы в имени функции-конструктора — это просто соглашение, оно не придает Foo никакого особого значения.

Ответ №1:

 Foo.prototype.update = function()
{
    var self = this;
    FB.api('/me/likes', function (response){ 
        self.bar["likes"] = response;
    });

}
  

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

В качестве альтернативы вы можете использовать команду ES5 bind или альтернативу jQuery $.proxy . или альтернативный вариант подчеркивания _.bind

 FB.api('/me/likes', (function (response){ 
    this.bar["likes"] = response;
}).bind(this));

FB.api('/me/likes', $.proxy(function (response){ 
    this.bar["likes"] = response;
}, this));

FB.api('/me/likes', _.bind(function (response){ 
    this.bar["likes"] = response;
}, this));
  

Все это гарантирует, что this значение в вашей функции соответствует вашим ожиданиям. (обратите внимание, что .bind это ES5 и ломается в старых браузерах).

Если у вас есть jQuery, вы можете использовать $.proxy. Если вы не хотите включать jQuery, включите вместо этого подчеркивание, потому что оно намного меньше