这个脚本的输出结果是:[[1, 2, 3, 4], 10] [[91, 92, 93, 94], 10] [[8888, 8888, 8888, 8888], 10] [['one', 'two', 'three', 'four'], 10]。但是,如果我取消注释hogs = [2, 4, 6, 8],输出结果是:[[1, 2, 3, 4], 10] [[1, 2, 3, 4], 10] [[1, 2, 3, 4], 10] [[1, 2, 3, 4], 10]。如果我把它注释掉,但是取消注释hogs = [333,444,555,666],输出结果是:[[1, 2, 3, 4], 10] [[91, 92, 93, 94], 10] [[8888, 8888, 8888, 8888], 10] [[8888, 8888, 8888, 8888], 10]。我想要充分理解简单的JavaScript闭包,以便能够预测它们的行为。除了分析引擎规范之外,这是否可能?我还想知道为什么用一个语句重新定义整个数组与逐个重新赋值数组的元素相比,具有如此不同的副作用。我害怕过于创新,因为我不知道如何预测副作用,而且我在文献中找不到线索。
我认为你并没有重复,当你写下“你不是在说‘告诉变量w引用hogs引用的任何对象’。你所说的是‘告诉变量w引用hogs当前时刻引用的任何对象’”时,你优雅地将整个事情概括了。你很好心地花时间详细解释了这一点。也许你同情那些简单地想象变量值搜索沿着作用域链向外进行直到必要时到达Object对象的语言学习者,而在这种情况下,封闭函数中的值被忽略,直到全局范围中的值被新定义所覆盖。知道改变数组中的值可以保持数组本身不变,但具有一些新的或更改的值分配;这与重新定义数组,使变量指向完全不同的东西非常非常不同。我脑海中浮现出一些静止的内存中的对象,而其他对象则消失并在内存中的其他位置重新出现;这与“该睡觉了”的押韵。对于可能对此感兴趣的其他人来说,所有对象似乎存在类似的情况,如下面的代码所示:
var x = 10;
var hogs = [1, 2, 3, 4];
var array5 = (function () {
var ar = [];
var z = x;
var w = hogs;
function g() {
ar.push(w);
ar.push(z);
return ar;
} return g;
})()();
console.log(array5);
//hogs = [2, 4, 6, 8]; Uncommenting this prevents array5 from changing.
x = 40;
hogs[0] = 91;
hogs[1] = 92;
hogs[2] = 93;
hogs[3] = 94;
console.log(array5);
hogs[0] = 8888;
hogs[1] = 8888;The output from this script is:
hogs[2] = 8888;
hogs[3] = 8888;
console.log(array5);
// hogs = [333, 444, 555, 666]; Un-commenting this prevents..
hogs[0] = 'one';
hogs[1] = 'two';
hogs[2] = 'three';
hogs[3] = 'four';
x = 40;
console.log(array5);
我认为你并没有重复,当你写下“你不是在说‘告诉变量w引用hogs引用的任何对象’。你所说的是‘告诉变量w引用hogs当前时刻引用的任何对象’”时,你优雅地将整个事情概括了。你很好心地花时间详细解释了这一点。也许你同情那些简单地想象变量值搜索沿着作用域链向外进行直到必要时到达Object对象的语言学习者,而在这种情况下,封闭函数中的值被忽略,直到全局范围中的值被新定义所覆盖。知道改变数组中的值可以保持数组本身不变,但具有一些新的或更改的值分配;这与重新定义数组,使变量指向完全不同的东西非常非常不同。我脑海中浮现出一些静止的内存中的对象,而其他对象则消失并在内存中的其他位置重新出现;这与“该睡觉了”的押韵。对于可能对此感兴趣的其他人来说,所有对象似乎存在类似的情况,如下面的代码所示:
enter code here
var x = 10;
var hogs = {'a': 1, 'b': 2, 'c' : 3, 'd' : 4};
var obj = {};
obj.h = hogs;
var ob5 = (function (arg) {
function g() {
var w = arg;
return w;
} return g;
})(hogs)();
console.log(ob5);
//hogs = [2, 4, 6, 8]; Uncommenting this prevents array5 from changing.
x = 40;
hogs['a'] = 91;
hogs['b'] = 92;
hogs['c'] = 93;
hogs['d'] = 94;
console.log(ob5);
hogs.a = 8888;
hogs.b = 8888;
hogs.c = 8888;
hogs.d = 8888;
console.log(ob5);
hogs = {'a':333, 'b':444, 'c':555, 'd':666}; // Prevents further changes.
hogs.a = 'one';
hogs.b = 'two';
hogs.c = 'three';
hogs.d = 'four';
x = 40;
console.log(ob5);