Javascript 使用apply()调用array.unshift会导致;超过最大调用堆栈大小;
此代码:Javascript 使用apply()调用array.unshift会导致;超过最大调用堆栈大小;,javascript,Javascript,此代码: var arr = []; arr.unshift.apply(arr, new Array(200000)); 原因:未捕获范围错误:超过最大调用堆栈大小 (见附件) 虽然此代码工作正常: var arr = []; arr.unshift(new Array(200000)); 知道为什么会发生这种情况吗?您的第一个示例相当于: arr.unshift(undefined, undefined, undefined, /* undefined 199,997 more tim
var arr = [];
arr.unshift.apply(arr, new Array(200000));
原因:未捕获范围错误:超过最大调用堆栈大小
(见附件)
虽然此代码工作正常:
var arr = [];
arr.unshift(new Array(200000));
知道为什么会发生这种情况吗?您的第一个示例相当于:
arr.unshift(undefined, undefined, undefined, /* undefined 199,997 more times */);
第二个示例只传递了unshift
一个参数,该参数是一个没有条目的数组,长度为200000
这是因为Function#apply
的目的是使用给定的This
参数值调用函数,然后将这些参数作为离散(单独)参数传递给目标函数
当要求JavaScript引擎调用具有200000个离散参数的函数时,JavaScript引擎会阻塞并不完全令人惊讶。(如果它起作用,我也不会感到惊讶。)
如果只想将数组作为单个参数传递,但想使用apply
-例如,使用call
:
arr.unshift.call(arr, new Array(200000));
call
传递的参数与您给它们的参数完全相同(第一个参数除外,它在调用过程中用作this
。您的第一个示例与此等效:
arr.unshift(undefined, undefined, undefined, /* undefined 199,997 more times */);
第二个示例只传递了unshift
一个参数,该参数是一个没有条目的数组,长度为200000
这是因为Function#apply
的目的是使用给定的This
参数值调用函数,然后将这些参数作为离散(单独)参数传递给目标函数
当要求JavaScript引擎调用具有200000个离散参数的函数时,JavaScript引擎会阻塞并不完全令人惊讶。(如果它起作用,我也不会感到惊讶。)
如果只想将数组作为单个参数传递,但想使用apply
-例如,使用call
:
arr.unshift.call(arr, new Array(200000));
call
将您提供给它的参数传递给它们,与您提供给它们的参数完全相同(第一个参数除外,第一个参数在调用过程中用作this
。函数#apply方法需要一个数组作为第二个参数。您应该采用带有括号的新阵列(200000)
:
var arr = [];
arr.unshift.apply(arr, [new Array(200000)]);
正如Chris所说,您还可以调用方法。调用,而不是。应用:
var arr = [];
arr.unshift.call(arr, new Array(200000));
函数#apply
方法需要一个数组作为第二个参数。您应该采用带有括号的新阵列(200000)
:
var arr = [];
arr.unshift.apply(arr, [new Array(200000)]);
正如Chris所说,您还可以调用方法。调用,而不是。应用:
var arr = [];
arr.unshift.call(arr, new Array(200000));
您使用的是哪种浏览器?它有一个编码糟糕的JavaScript引擎。工作正常这两种代码不相等。您正在寻找。请调用,而不是。应用。谢谢,我现在明白了为什么它们不是等效的。您使用的是哪种浏览器?它有一个编码糟糕的JavaScript引擎。工作正常这两种代码不相等。您正在寻找.call
而不是.apply
。谢谢,我现在明白了为什么它们不相等。或者干脆用call
而不是apply
。谢谢,我现在明白了区别。我真正想知道的是,为什么arr.unshift.apply(arr,new Array(200000))抛出错误,而T.J.的回答澄清了这一点。或者只是使用call
而不是apply
。谢谢,我现在理解了其中的区别。我真正想知道的是为什么arr.unshift.apply(arr,newarray(200000))抛出错误,而T.J.的回答澄清了这一点。谢谢!你知道为什么有人会采取第一种方法将一个数组复制到另一个数组中(想象一个有效的数组而不是新的数组(20000))?我从一个JavaScript库(ExtJs)中提取了这段代码,所以无论是谁写的,都有一些想法。@SergiuB:JavaScript数组缺少一个相当明显的功能:append
。与中一样,a.append(b)
获取b
的所有内容,并将它们添加到a
的末尾。有a.concat(b)
,但它创建了一个新数组,其中包含a
的内容,后跟b
的内容。因此,尽管我从未见过使用unshift
,但我见过()使用a.push.apply(a,b)
来执行此操作。我从未尝试过使用大型数组,但对于“合理”数量的元素,它工作得很好。我现在理解了这项技术,很酷。最后,我将unshift.apply调用和巨大的数组参数拆分为几个较小的调用,以避免调用堆栈超出错误。谢谢!你知道为什么有人会采取第一种方法将一个数组复制到另一个数组中(想象一个有效的数组而不是新的数组(20000))?我从一个JavaScript库(ExtJs)中提取了这段代码,所以无论是谁写的,都有一些想法。@SergiuB:JavaScript数组缺少一个相当明显的功能:append
。与中一样,a.append(b)
获取b
的所有内容,并将它们添加到a
的末尾。有a.concat(b)
,但它创建了一个新数组,其中包含a
的内容,后跟b
的内容。因此,尽管我从未见过使用unshift
,但我见过()使用a.push.apply(a,b)
来执行此操作。我从未尝试过使用大型数组,但对于“合理”数量的元素,它工作得很好。我现在理解了这项技术,很酷。最后,我将unshift.apply调用和巨大的数组参数拆分为几个较小的调用,以避免调用堆栈超出错误。