javascript 来自你不懂 JS 的模块模式
javascript module pattern from You don't know JS
我已经阅读和测试下面的代码几个小时了,但我似乎无法理解某些事情。
我一直在逐步检查 chrome 控制台,基本上在我可以添加的每一行中都设置了中断,并且一直在检查,我只是不确定事情
1)我只是不确定 deps 数组的用途。对我来说第一件奇怪的事情是,为什么脚本不尝试在第一次调用它时(来自 MyModules.define("bar",[],function()
)尝试放入数据?
为什么脚本第二次调用 define(MyModules.define("foo",["bar"], function(bar)
) 然后将 ["bar"] 添加到数组,而第一次定义应该首先完成它?
2)此代码modules[name] = impl.apply(impl,deps)
。每个回调,不要使用 'this'.. 所以这里有必要申请吗?另外,这可能是我在使用 'apply' 时对回调缺乏理解,但是如何阅读呢?我认为 'apply' 通常会
functionName.apply(obj,[])
在这种情况下,这几乎就像在说
functionName.apply(functionName, []) ??
或者这是不同的,因为函数本身是匿名的?
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
};
})
MyModules.define("foo",["bar"], function(bar) {
var hungry = "hippo";
function awesome() {
console.log(bar.hello(hungry).toUpperCase() );
}
return {
awesome: awesome
};
});
var bar = MyModules.get("bar");
var foo = MyModules.get("foo");
console.log(bar.hello("hippo"));
foo.awesome();
I am just not sure of the purpose of deps
array.
您似乎对整个 MyModules
对象的用途感到困惑,不是吗?
define
方法可用于声明一个模块,带有名称、依赖项数组和工厂函数:
name
是模块对象将存储在 modules
字典中的字符串
deps
数组包含当前声明的模块所依赖的模块的名称。
- 将调用
impl
函数来创建将在 name
下可用的模块对象。它确实传递了 deps
数组中的名称被解析到的模块对象。
Why doesn't script try to put data on first call to it (from MyModules.define("bar",[],function()
) ? Why does script make second call to define (MyModules.define("foo",["bar"], function(bar)
)?
意思是声明一个名为bar
的模块没有任何依赖,声明一个名为foo
的模块依赖于bar
。通常,这两个声明将放在不同的脚本中。
This code modules[name] = impl.apply(impl,deps)
- Each callbacks, do not use 'this'.. so was apply necessary here?
是的,这里需要 apply
才能将任意多个参数传递给函数。但是,为this
值传递impl
函数确实没有任何意义,null
在这里更合适。
更好、更容易理解的定义是
function define(moduleName, dependencyNames, factory) {
var dependencies = [];
for (var i=0; i<dependencyNames.length; i++) {
dependencies[i] = get(dependencyNames[i]); // resolve name
}
modules[moduleName] = factory.apply(null, dependencies);
}
我已经阅读和测试下面的代码几个小时了,但我似乎无法理解某些事情。 我一直在逐步检查 chrome 控制台,基本上在我可以添加的每一行中都设置了中断,并且一直在检查,我只是不确定事情
1)我只是不确定 deps 数组的用途。对我来说第一件奇怪的事情是,为什么脚本不尝试在第一次调用它时(来自 MyModules.define("bar",[],function()
)尝试放入数据?
为什么脚本第二次调用 define(MyModules.define("foo",["bar"], function(bar)
) 然后将 ["bar"] 添加到数组,而第一次定义应该首先完成它?
2)此代码modules[name] = impl.apply(impl,deps)
。每个回调,不要使用 'this'.. 所以这里有必要申请吗?另外,这可能是我在使用 'apply' 时对回调缺乏理解,但是如何阅读呢?我认为 'apply' 通常会
functionName.apply(obj,[])
在这种情况下,这几乎就像在说
functionName.apply(functionName, []) ??
或者这是不同的,因为函数本身是匿名的?
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
};
})
MyModules.define("foo",["bar"], function(bar) {
var hungry = "hippo";
function awesome() {
console.log(bar.hello(hungry).toUpperCase() );
}
return {
awesome: awesome
};
});
var bar = MyModules.get("bar");
var foo = MyModules.get("foo");
console.log(bar.hello("hippo"));
foo.awesome();
I am just not sure of the purpose of
deps
array.
您似乎对整个 MyModules
对象的用途感到困惑,不是吗?
define
方法可用于声明一个模块,带有名称、依赖项数组和工厂函数:
name
是模块对象将存储在modules
字典中的字符串deps
数组包含当前声明的模块所依赖的模块的名称。- 将调用
impl
函数来创建将在name
下可用的模块对象。它确实传递了deps
数组中的名称被解析到的模块对象。
Why doesn't script try to put data on first call to it (from
MyModules.define("bar",[],function()
) ? Why does script make second call to define (MyModules.define("foo",["bar"], function(bar)
)?
意思是声明一个名为bar
的模块没有任何依赖,声明一个名为foo
的模块依赖于bar
。通常,这两个声明将放在不同的脚本中。
This code
modules[name] = impl.apply(impl,deps)
- Each callbacks, do not use 'this'.. so was apply necessary here?
是的,这里需要 apply
才能将任意多个参数传递给函数。但是,为this
值传递impl
函数确实没有任何意义,null
在这里更合适。
更好、更容易理解的定义是
function define(moduleName, dependencyNames, factory) {
var dependencies = [];
for (var i=0; i<dependencyNames.length; i++) {
dependencies[i] = get(dependencyNames[i]); // resolve name
}
modules[moduleName] = factory.apply(null, dependencies);
}