Обычно функция jQuery события ready
вызывается следующим образом:
$(function() { /* ... */ });
// or
jQuery(function() { /* ... */ });
// or
jQuery(document).ready(function() { /* ... */ });
Суть в том, что функции не присвоен конкретный контекст;фактический контекст, заданный функцией jQuery, является элементом HTMLDocument
, независимо от аргумента (в последнем примере, document
).Почему это так, это другой предмет.
Обычно каждая из этих функций вызывается позже, после того, как все загружено, но не обязательно.В вашем случае есть ссылка на MyNameSpace
до того, как произойдет событие ready
.Даже если Javascript является языком типа LALR , и он найдет символ, объявленный позже, это не очень хорошая практика.Что если позже MyNameSpace
будет установлен на что-то другое, прежде чем jQuery вызовет функции обратного вызова ready
?Ваш ready
обратный вызов не получит эту новую ссылку.Если нет преднамеренного, ссылка должна быть сделана внутри обратного вызова ready
, когда все ... готово.
Затем внутри обратного вызова ready
существуют другие методы дляназначить контекст для функции. loneomeday в значительной степени дали правильный способ выполнить то, что вы пытаетесь сделать.
(function() {
// this == MyNamespace
}).call(MyNamespace);
Приведенный выше код выполняет анонимную функцию сразу, где this == MyNameSpace
примечание : разница между применяется и вызов расшифровывается здесь
Теперь идет нижняя частькод, который вы указали:
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
onReadyCallback.apply(window);
});
});
Это проблематично и не нужно.Нужна ли там только функция onReadyCallback
или она будет вызываться несколько раз?Если его нужно вызывать только один раз, сэкономьте глобальное пространство имен и просто сделайте:
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
// if everything is done loading, the function will be executed, otherwise
// it's execution will be postponed later
jQuery(function() {
// create our nicely wrapped anonymous function now
(function() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
})(MyNameSpace); // grab our most recent reference of `MyNameSpace`
});
});
});
Если вам не нравится отступ (это просто вкус разработчика), замените все в ready
обратный вызов с (что-то вроде):
initMyNameSpace.apply(MyNameSpace);
и создание вашей функции снаружи, в глобальном пространстве:
function initMyNameSpace() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
};
Но я бы рекомендовал, по крайней мере, поместить ее в require
функция обратного вызова, так что ...
- ... не загрязняет глобальное пространство имен функцией однократного выполнения
- ... нигде не доступен (сохраните ееprivate)
- ... можно быстро найти при редактировании исходного кода
- и т. д.
note : обычно apply и call используются, чтобы избежать повторного доступа к объектам, таким как some.thing.pretty.deep = value;
или когда одна функция должна быть применена ко многим, но не ко всем объектам, и, таким образом, расширение прототипа объекта просто не очень хорошая идея.
В любом случае, это мое мнение, и как бы я поступил безбольше знаний о вашем коде или о том, что вы делаете.