2016-06-08 2 views
2

Я определил вспомогательный класс для создания некоторых объектов. Как объекты A содержат Bs, я пытаюсь вызвать createB из createA, но получаю «Uncaught ReferenceError: createB не определен». JS не мой основной язык так пожалуйста, прости меня, если это что-то очевидно;)Javascript - Доступ к статическому методу из другого статического метода throws ReferenceError

Вот мой код:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    return { 
    addTo: function (params, key, target, source) { 
     if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
     } 
    }, 
    createA: function (params, source) { 
     var result = new A(); 

     ... 
     bDefs.forEach(function(bDef) { 
     result.get("bs").push(this.createB(params,source)); 
     }); 
     return result; 
    }, 
    createB: function (params, source) { 

     var result = new B(); 
     ... 

     result.get("cs").push(createC(params,source)); 
     return result; 
    }, 
    createMediaType: function (params, source) { 

     var result = new C(); 
     ... 

     return result; 
    } 
    }; 
}); 

EDIT: чтение этот вопрос еще раз я заметил, что я опущено что-то важное, что может быть причина проблемы: я вызываю createB() изнутри forEach. Я полагаю, что анонимная функция не имеет видимости остальной части класса. Как я могу передать ссылку на на forEach?

+0

Это не хорошо на SO редактировать вопрос такой, что редактирование аннулирует существующие ответы на вопрос так, как было, поэтому я удалил 'this.' из вызова' createB', который вы добавили с помощью редактирования. Как сказано в [algiogia] (http://stackoverflow.com/questions/37696799/javascript-accessing-static-method-from-another-static-method-throws-reference/37696945?noredirect=1#comment62869281_37696945), решение в мой ответ также касается проблемы 'forEach'. Я также обновил ответ, чтобы показать вам, как сделать работу 'forEach', если вы хотите продолжить использование' this'. –

+0

@ T.J.Crowder Я отредактировал вопрос, потому что это было неправильно. Копирование кода в SO Я пропустил соответствующую часть. В первоначальной версии я также упомянул, что уже пытался использовать «this.createB()». Ваш ответ по-прежнему действителен. – algiogia

+0

Даже если вы просто разместили код неправильно, было бы неуместно, если бы он исправил его * после получения ответа, который был признан недействительным *. Однако, как вы заметили, ваш первоначальный вопрос * сделал * в конце этого вопроса о 'this.createB' (я пропустил это!), Поэтому в этом случае он не применяется. Кстати, в моем комментарии выше, я имел в виду «как сказал джамец», а не «как сказал альгогия» - да! –

ответ

1

Эта линия

result.get("bs").push(createB(params,source)); 

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

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

I'm calling createB() from within a forEach . I suppose that anonymous function does not have visibility of the rest of the class.

Да, это так. (И это не класс.)

How can I pass a reference to this to the forEach ?

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

bDefs.forEach(function(bDef) { 
    result.get("bs").push(this.createB(params,source)); 
}, this); 
// ^^^^ 

или поочередно Вы можете использовать Function#bind, но я Wouldn 'там.

Если вы использовали ES2015 (ака «ES6»), вы можете использовать функцию стрелки, так как стрелка функций, близких по значению this контекста, в котором они создаются:

// Requires ES2015 ("ES6") 
bDefs.forEach(bDef => { 
    result.get("bs").push(this.createB(params,source)); 
}); 

У вас есть второй вариант, который не полагается на вызывающий код для вызова с правильным значением this и не требует сохранения этого значения в пределах forEach: вы можете выполнять эти функции отдельно стоящих идентификаторов в частной области, а также возвращать их как свойств на объекте:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    // Note how each of these is a function declaration; that defines 
    // their names as in-scope identifiers within this anonymous function 
    // and the functions created within it (which close over the context of 
    // the call to this anonymous function where these are created). 
    function addTo(params, key, target, source) { 
    if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
    } 
    } 

    function createA(params, source) { 
    var result = new A(); 

    ... 
    result.get("bs").push(createB(params,source)); 

    return result; 
    } 

    function createB(params, source) { 

    var result = new B(); 
    ... 

    result.get("cs").push(createC(params,source)); 
    return result; 
    } 

    function createMediaType(params, source) { 

    var result = new C(); 
    ... 

    return result; 
    } 

    // Now we return the object 
    return { 
     addTo: addTo, 
     createA: createA, 
     createB: createB, 
     createMediaType: createMediaType 
    }; 
}); 

Side Примечание: В ES2015 (ака «ES6»), что объект инициализатор в конце может быть немного более кратким:

// Requires ES2015 (aka "ES6") 
return { 
    addTo, 
    createA, 
    createB, 
    createMediaType 
}; 
+0

Спасибо. Я обнаружил, что проблема - это forEach (см. Обновленный вопрос). – algiogia

+1

@algiogia, если вы сделаете это так, как показано в этом ответе, он также решает проблему 'forEach'. – Jamiec

+0

@algiogia: Есть ли что-то еще, что вам нужно уточнить? –

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

  • Нет связанных вопросов^_^