我正在开发一个JavaScript库,而我需要相应地加载不同的模块,我使用回调来加载不同的脚本:
只需在页面中添加main
脚本:
<script type="text/javascript" src="main.js"></script>
main.js:
(function () {
var actionForT2 = function (fun) {
fun && fun.apply(this);
}
var loadCallback = function (name, obj) {
if (name == "t2") {
actionForT2(obj);
}
}
window.__jsload = loadCallback;
var loadJs = function (js) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement("script");
script.setAttribute("src", js);
script.setAttribute("type", "text/javascript");
head.appendChild(script);
}
loadJs("js/t2.js");
})();
t2.js:
__jsload('t2', function () {
console.info("t2 loaded");
console.info(loadJs);
})
现在t2.js
将按预期加载。我得到了输出:
t2 loaded
ReferenceError: loadJs is not defined
也就是说,loadJs
中定义的函数不会访问t2.js
函数,然后我想知道是否可以更改加载函数的运行时上下文,例如,当加载函数时被称为:
fun && fun.apply(this);
是否可以在当前匿名函数的上下文中调用fun
,然后loadJs
可以访问所有已定义的变量,fun
等函数,而无需window
将它们导出到https://maps.gstatic.com/maps-api-v3/api/js/18/3/main.js
?
为什么我对这种解决方案感兴趣的是我发现谷歌地图使用回调,例如,当使用谷歌地图v3时,以下脚本将被加载到页面:
map
然后将加载另一个模块https://maps.gstatic.com/cat_js/maps-api-v3/api/js/18/3/{map}.js
:
{map}.js
当深入到代码时,我发现main.js
可以访问{{1}}中定义的变量。但是我找不到魔法是如何发生的。
答案 0 :(得分:2)
是否可以更改函数运行时范围...我想知道是否可以更改已加载函数的运行时上下文,例如,在调用加载的函数时
没有。 Javascript是词法范围的,因此范围完全取决于代码中创建函数的位置,而不是它们调用的位置或它们的调用方式
> fun && fun.apply(this);
这只会设置函数执行上下文的一个参数,即 this 参数。
关于术语 context 存在一般性的混淆。在ECMA-262(支持javascript的语言标准)中, context 仅在execution context中使用,entire environment是函数内的identifier resolution并包含其 this < / em>参数。
调用和 apply 方法允许您指定函数 this 的值,就是这样,它们对其没有任何其他影响执行上下文(这就是此永远不应被称为“上下文”的原因)。它们对Identifier Resolution, Execution Contexts and scope chains没有任何影响,{{3}}根据范围继续进行,无论 this 的值是什么,或者调用函数的位置。
您可能会发现以下文章:{{3}}。
答案 1 :(得分:0)
你可以把它变成全球性的。由于您已经拥有window.__jsload
,因此可以将其附加在那里。
__jsload.loadJs = loadJs;
// // access like this :
// console.info(__jsload.loadJS);
或者,当您从__jsload
调用它时,您可以将其传递给回调。
__jsload('t2', function (loadJs) {
console.info("t2 loaded");
console.info(loadJs);
}