Javascript 你没有';我不知道JS模块加载器

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++

我正在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++) {
            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作为函数参数,因为它在全局范围内(也在严格模式下)
如果我删除impl一个,它的工作原理与原始代码相同

"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(){
...