gpt4 book ai didi

javascript - 为什么这个 JavaScript 闭包数组保留旧值

转载 作者:行者123 更新时间:2023-11-30 16:14:18 25 4
gpt4 key购买 nike

我在 java 脚本闭包和数组方面遇到了一个有趣的情况。我不确定 javascript 的哪一部分导致了参数数组的缓存。

var SLICE = Array.prototype.slice;

var attach = function(method) {
var args = SLICE.call(arguments, 1);
return function() {
args = args.concat(SLICE.call(arguments, 0));
method.apply(null, args);
};
};

function foo(param1, param2, param3) {
console.log(param1, param2, param3);
};

var bar = attach(foo, 1, 2);
bar(3);
bar(4);

上面代码的输出是

1 2 3
1 2 3

代替

1 2 3
1 2 4

如果将代码更改为,则获得正确的输出

var SLICE = Array.prototype.slice;

var attach = function(method) {
var args = SLICE.call(arguments, 1);
return function() {
method.apply(null, args.concat(SLICE.call(arguments, 0)));
};
};

function foo(param1, param2, param3) {
console.log(param1, param2, param3);
};

var bar = attach(foo, 1, 2);
bar(3);
bar(4);

输出是

1 2 3
1 2 4

我想知道,java脚本的哪个属性是造成这种情况的原因?

编辑:代码已被编辑以删除推送,并更好地解释场景

最佳答案

foo 函数只接受三个参数,

function foo(param1, param2, param3) {

而且它只被发送了三个

method(args[0], args[1], args[2]);

然而,push() 推送到数组,所以当您有 [1,2,3,4] 时,只有前三个被发送,而不是第四个.

如果函数接受了四个参数

var SLICE = Array.prototype.slice;

var attach = function(method) {
var args = SLICE.call(arguments, 1);

return function() {
for (var key in arguments) {
args.push(arguments[key]);
}
method(args[0], args[1], args[2], args[3]);
};
};

function foo(param1, param2, param3, param4) {
console.log(param1, param2, param3, param4);
};

var bar = attach(foo, 1, 2);
bar(3);
bar(4);

您将在控制台中得到 1 2 3 4

换句话说,这与缓存无关,也与未添加的值无关,只是函数在将新值推送到数组时没有接受足够的参数。

更好的方法是接受任意数量参数的函数

var SLICE = Array.prototype.slice;

var attach = function(method) {
var args = SLICE.call(arguments, 1);

return function() {
args = args.concat( SLICE.call(arguments) );
method.apply(null, args)
};
};

function foo() {
console.log(arguments);
};

var bar = attach(foo, 1, 2);
bar(3);
bar(4);

问题中的第二个代码片段没有继续添加到数组的原因是因为数组没有存储,concat返回一个新数组,它不会改变原来的,所以它必须是

args = args.concat(array);

存储更改。由于您没有存储更改,因此每次调用内部函数时,它都会获取原始数组 [1,2] 并向其添加一个值,然后返回它。

因为它没有存储,所以第一次调用 bar(3) 时它需要 [1,2] 并添加 3,并且你最终得到了 [1,2,3]
下次调用该函数时,它只是做同样的事情,获取 [1,2] 并添加 4 等等,最后得到 [1,2,4] 代替。

关于javascript - 为什么这个 JavaScript 闭包数组保留旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35755617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com