尽管已经阅读了有关Javascript模块模式的all the usual教程,但仍有一些关于范围界定的内容,我显然不明白。
push
在模块范围内列出了我期望它做的事情。使用=
设置模块范围的列表不会。我在这里做错了什么?
var MODULE = MODULE || {};
MODULE.Submodule = (function(){
var foo = [],
bar = [];
var init = function() {
foo = ['a','b','c']; // This doesn't set MODULE.Submodule.foo
bar.push('a'); // But this works as expected
console.log('foo: ' + MODULE.Submodule.foo); // foo:
console.log('bar: ' + MODULE.Submodule.bar); // bar: a
}
return {
init: init,
foo: foo,
bar: bar
}
}());
MODULE.Submodule.init();
答案 0 :(得分:2)
这个JSFiddle http://jsfiddle.net/SwBLk/1/可能有助于解释发生了什么:
var MODULE = MODULE || {};
MODULE.Submodule = (function(){
var foo = [],
bar = [];
var init = function() {
console.log(MODULE.Submodule.foo === foo);
foo = ['a','b','c']; // This doesn't set MODULE.Submodule.foo
console.log(MODULE.Submodule.foo === foo);
bar.push('a'); // But this works as expected
console.log('foo: ' + MODULE.Submodule.foo); // foo:
console.log('bar: ' + MODULE.Submodule.bar); // bar: a
}
return {
init: init,
foo: foo,
bar: bar
}
}());
MODULE.Submodule.init();
第一个布尔检查返回TRUE,因为两个对象都引用同一个对象。 第二个布尔检查返回FALSE,因为你已经用一个新对象替换了foo,并且引用不再指向同一个底层对象。
当您为其重新分配新数组时,您将使用对新数组的引用替换foo数组。
执行IIFE时,您可以为非常具体的版本指定" foo"在退货声明中。这是您在调用MODULE.Submodule.foo时访问的引用。当你进入并替换foo = [" a",...]时,你正在替换对象foo,但不替换MODULE.Submodule对象中对它的引用。
编辑:你如何解决这个问题?1)理想情况下,您不能替换整个阵列,但只能清除&在init()调用上重新初始化它:
MODULE.Submodule = (function(){
var foo = [],
bar = [];
var init = function() {
// Clear our the array if it already contains data (in case your calling "init" more than once)
// This method is documented to be the fastest way to clear out an array, referenced here:
// http://stackoverflow.com/questions/1232040/how-to-empty-an-array-in-javascript
while(foo.length > 0) {
foo.pop();
}
foo.push('a');
foo.push('b');
foo.push('c');
bar.push('a'); // But this works as expected
console.log('foo: ' + MODULE.Submodule.foo); // foo:
console.log('bar: ' + MODULE.Submodule.bar); // bar: a
}
2)你的第二个选择是使用我所说的"动态吸气者" (工作小提琴:http://jsfiddle.net/6zVcP/):
var MODULE = MODULE || {};
MODULE.Submodule = (function(){
var foo = [],
bar = [];
var init = function() {
foo = ['a','b','c']; // This doesn't set MODULE.Submodule.foo
bar.push('a'); // But this works as expected
console.log('foo: ' + MODULE.Submodule.foo()); // foo:
console.log('bar: ' + MODULE.Submodule.bar()); // bar: a
}
var modify = function()
{
foo = [];
foo.push("test");
}
return {
init: init,
modifyArrays: modify,
foo: function() { return foo; },
bar: function() { return bar; }
}
}());
MODULE.Submodule.init();
MODULE.Submodule.modifyArrays();
console.log(MODULE.Submodule.foo());
这允许您对foo对象执行任何操作,而getter将始终返回最新的引用。