Javascript 你没有';我不知道JS模块加载器
我正在github上阅读“You't know JS”(第一版),我正在使用第5章中的模块加载程序示例。但有两件事我不明白。我在这里找到了同一个模块加载器()的另一个问题,但它没有回答我的问题 首先是原始代码:Javascript 你没有';我不知道JS模块加载器,javascript,module,Javascript,Module,我正在github上阅读“You't know JS”(第一版),我正在使用第5章中的模块加载程序示例。但有两件事我不明白。我在这里找到了同一个模块加载器()的另一个问题,但它没有回答我的问题 首先是原始代码: var MyModules = (function Manager() { var modules = {}; function define(name, deps, impl) { for (var i=0; i<deps.length; i++
var MyModules = (function Manager() {
var modules = {};
function define(name, deps, impl) {
for (var i=0; i<deps.length; i++) {
deps[i] = modules[deps[i]];
}
modules[name] = impl.apply( impl, deps );
}
function get(name) {
return modules[name];
}
return {
define: define,
get: get
};
})();
MyModules.define( "bar", [], function(){
function hello(who) {
return "Let me introduce: " + who;
}
return {
hello: hello
};
} ); // module["bar"] = hello(who) & deps = []
MyModules.define( "foo", ["bar"], function(bar){
var hungry = "hippo";
function awesome() {
console.log( bar.hello( hungry ).toUpperCase() );
}
return {
awesome: awesome
};
} ); // module["foo"] = awesome() & deps = [hello(who)]
var bar = MyModules.get( "bar" );
var foo = MyModules.get( "foo" );
console.log(
bar.hello( "hippo" )
); // Let me introduce: hippo
foo.awesome(); // LET ME INTRODUCE: HIPPO
- 为什么我要在foo的定义中将bar作为函数参数,因为它在全局范围内(也在严格模式下)
"use strict";
...
modules[name] = impl.apply( deps );
...
MyModules.define( "foo", ["bar"], function(){
...
这两件事是不必要的,还是代码工作的巧合
为什么impl应用于自身(加上deps对象)?我曾经研究过apply()的工作原理。在第一个示例中,只有一个应用于函数的对象,而不是函数本身加上一个对象
查看MDN。通常MDN包含更多信息,因此值得参考
调用apply()
时,第一个参数是已执行函数的this
值。在很多情况下,该值是什么并不重要-如果您不关心它,也可以传递null
constthisvalue={foo:3};
使用此()的函数{
返回此.foo+2;
}
console.log(使用this.apply(thisValue));//3 + 2 = 5
函数notUsingThis(){
返回8;
}
console.log(不使用此.apply(此值));//8.
console.log(不使用此.apply(null));//8
“这两件事是不必要的还是巧合,代码可以工作?”您已经彻底更改了模块加载程序的语义,但他们更改了模块定义的语义以匹配它。因此,它的工作不是“巧合”,但我不会说代码是“不必要的”代码>到var xyz=…
,您的代码将不再运行。我建议看看它是如何工作的,它应该能回答你大部分的问题。我的问题看起来很愚蠢,那就是被否决了。我曾经研究过apply()的工作原理。在第一个示例中,只有一个应用于函数的对象,而不是函数本身加上一个对象。“因为它在全局范围内”,如果它不在呢?模块通常是分开的,所以它们不会和全局范围混在一起。仅仅因为这个示例显示了可以避免这种情况的用法,并不意味着它适用于一般情况。@biberman当您调用apply
时,第一个参数是已执行函数的this
值。在很多情况下,该值是什么并不重要-如果您不关心它,也可以传递null
。但是,此模块加载器会传递正在加载的模块。这也是一个合理的决定,因为如果在内部使用this
,它至少是合理的-不是全局对象,也不是可能导致错误的null
。如果此
未被初始化,则值是什么无关紧要。
MyModules.define( "foo", ["bar"], function(bar){
"use strict";
...
modules[name] = impl.apply( deps );
...
MyModules.define( "foo", ["bar"], function(){
...