#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, включите вместо этого подчеркивание, потому что оно намного меньше