2014-09-18 3 views
0

У меня есть немного рассола.JavaScript-ответ на экземпляр объекта 'undefined'

Я создал сладкий плагин javascript, который отлично работал. Но потом я решил, что если мне нужно запустить несколько версий плагина, мне придется создавать несколько экземпляров.

Но тогда ... Я заметил что-то, мои обратные вызовы не обращаются. Я сузил виновника до того, что я больше не могу ссылаться на this из-за сценария, на который нужно ссылаться.

Мой вопрос в том, что (код следует). как вы ссылаетесь на экземпляр объекта в Javascript, так как this не работает.

Это фрагмент кода.

Ранее

Код подмости используется для выглядеть, как это, и она работала без проблем:

var list = (function() { //code }());

Но, так что я могу создать экземпляр моего объекта, я изменил его такие как:

var list = (function() { //code }); 

И так, как раньше я бы назвал list.init(); непосредственно, теперь я создаю новый экземпляр этого:

var test = new list("test");

перед вызовом.

В объекте списка есть несколько функций, один из которых запускает запрос ajax, заполняя объект данными и передавая этот объект скрипту, который обрабатывает запросы. В объекте есть функция, обратный вызов к этому объекту, давайте посмотрим на этот метод:

makeTemplateRequest = function() { 
    console.log('make template request called'); 
    var send = new JaysHelpers.Ajax.sendObject(); 
    send.page = "/list.html", 
    send.request = "widget", 
    send.blockNumber = 0, 
    send.numberOfItems = 1, 
    send.filters = [], 
    send.callBack = templateCallback; 


    gateKeeper.request({ 
     speed: "now", 
     sendObj: send, 
     recur: false    
    }); 

}, 

Проблема здесь:

 send.callBack = me.templateCallback; 

Это должно быть ссылок на метод, который Аякса плагин перезванивает:

templateCallback = function(jsonObject, error){ //callbackcode },

Но вместо этого он 'не определен'.

Я пробовал несколько вещей, я пытался зарезервировать this в локальном пространстве сценария как var me = this; Но это фактически резервирует глобальное пространство имен. Я пробовал this.templateCallback, но это то же самое, что и предыдущий, Ive пытался называть его внешним list.templateCallback, но теперь плагин требует создания экземпляра, что не работает. Я пробовал ссылаться на него локально как templateCallback, но это не работает.

Также обратите внимание, что эти функции доступны через:

return { 
    init: init, 
    callback: callback, 
    templateCallback: templateCallback  
}; 

Вопрос

Так что мой вопрос заключается в следующем, как я ссылаться this экземпляр объекта?

РЕДАКТИРОВАТЬ

Более полный код:

var list = (function() { 

"use strict"; 

var init = function (options) { 


    //check and verify data passed in 
    // if happy make the call below 
    makeTemplateRequest(); 

}, 
makeTemplateRequest = function() { 
    console.log('make template request called'); 
    var send = new JaysHelpers.Ajax.sendObject(); 
    send.page = "/list.html", 
    send.request = "widget", 
    send.blockNumber = 0, 
    send.numberOfItems = 1, 
    send.filters = [], 
    send.callBack = templateCallback; 

    gateKeeper.request({ 
     speed: "now", 
     sendObj: send, 
     recur: false    
    }); 

}, 

templateCallback = function (html, error) { var thisHtml = html || ""; //do stuff with returned data };

return { 
    init: init, 
    callback: callback, 
    templateCallback: templateCallback  
}; 

});

+0

Если вы собираетесь использовать 'new' для создания нового экземпляра, не' возврата 'от функции. Просто установите их как свойства 'this'. Тогда у вас будет доступ к ним «публично» точно так же – Ian

+0

@Ian: В общем, хороший совет, хотя если вы * сделаете * вернуть объект, тот, созданный с помощью 'new', будет отброшен, а тот, который вы вернете, используется вместо , –

+0

@ T.J.Crowder Интересно, не уверен, что я это знал. Опять же, я никогда не пытался смешивать эти методологии :) – Ian

ответ

0

Код

send.callBack = me.templateCallback; 

присвоит ссылку на функцию к send.callBack, но не будет делать ничего, чтобы сохранить значение me (что было бы this во время вызова templateCallback). Чтобы сделать это, вы можете использовать ES5-х Function#bind (который может быть подкладки на старых браузерах):

send.callBack = me.templateCallback.bind(me); 

Function#bind создает функцию, которая при вызове будет вызывать оригинальную функцию с this набором аргумента вы даете ему.

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

Больше (в моем блоге):

+0

Но не сохранит ли это '' ', если вы его правильно назовете? Например, 'test.templateCallback()'? Я думаю, что проблема в том, как определяется 'templateCallback' - обратите внимание на то, как ссылается' templateCallback' в 'return' - как локальная переменная, а не на свойство' me' (или 'this' или что-то еще) – Ian

+0

@Ian: Если вы выполняете 'test.templateCallback()', в 'templateCallback',' this' будет 'test'. Но это почти наверняка ** не **, как это вызывает код, вызывающий 'send.callBack'. –

+1

Дерьмо дерьмо, я просто сбиваю с толку. Я знаю, как правильно обрабатывать «это» (как вы показали), я просто путаю переменные и прочее. Не обращайте внимания на то, что я говорю о – Ian

Смежные вопросы