Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 还有一个调用vs Apply查询_Javascript - Fatal编程技术网

Javascript 还有一个调用vs Apply查询

Javascript 还有一个调用vs Apply查询,javascript,Javascript,当我尝试运行以下代码时: function flatten(a) { return [].slice.call(arguments).reduce(function(acc, val) { return acc.concat(Array.isArray(val) ? flatten.call(null, val) : val); }, []); } 我得到了以下错误: 未捕获范围错误:超过最大调用堆栈大小 但是如果我使用了flatte.apply而不是flatte.call,它

当我尝试运行以下代码时:

function flatten(a) {
  return [].slice.call(arguments).reduce(function(acc, val) {
    return acc.concat(Array.isArray(val) ? flatten.call(null, val) : val);
  }, []);
}
我得到了以下错误:

未捕获范围错误:超过最大调用堆栈大小

但是如果我使用了
flatte.apply
而不是
flatte.call
,它就可以完美地工作。(深度展平输入阵列)

除此之外,我很少阅读其他博客和文章来理解它为何如此。我要么找不到答案,要么我一定是忽略了。(如果是后一种情况,请原谅我的怒视)

当然,这二者之间的根本区别在于:

应用-要求可选参数为数组

调用-要求显式列出可选参数

通常,函数可以采用任何类型的参数—原语和非原语。因此,我的问题是:

  • 调用方法的可选参数之一是
    Array
    类型还是其他非基本类型

  • 当使用
    call
    时,为什么上面的代码超过了调用堆栈


  • 编辑:因为使用了2种
    call
    方法,所以我的描述不明确。我做了一些更改来澄清。

    当您调用
    flatte.call(null,val)
    时,
    val
    是一个数组,
    flatte
    函数作为参数
    val
    接收您作为可选参数传递给
    call
    (类型未选中),因此
    参数
    [val]/code>

    您可以看到
    val
    数组位于数组中。当您调用
    reduce
    时,回调中的
    val
    仍将是一个数组,您什么也没有展平,这就是它从不停止的原因


    调用
    flatte.apply(null,val)
    时,
    val
    是一个数组,
    flatte
    函数作为参数接收
    val
    的元素,因此
    参数与
    val
    相同(不是
    [val]
    ):您已经有效地打开了数组。这就是它工作的原因。

    您的错误在这里:

    [].slice.call(arguments).reduce
                  ^^^^^^^^^
    
    因此,当您通过
    [x]
    时,您在
    [[x]]
    上调用
    reduce
    ,第一个
    val
    变为
    [x]
    。然后您再次使用
    [x]
    调用
    flatten
    ,故事就会重复

    另一方面,
    apply(…,val)
    只将
    x
    传递到
    flatten
    ,从而将嵌套级别降低一级

    如果您对如何使用
    apply
    展平深度嵌套数组感兴趣,则无需递归即可:

    while(ary.some(Array.isArray))
      ary = [].concat.apply([], ary);
    
    下面是
    call
    vs
    apply
    的一个小例子:

    函数fun(){
    var len=arguments.length;
    文档。写“我有”
    +莱恩
    + " " 
    +(len>1?“参数”:“参数”)
    + ": " 
    +stringify(参数)
    +“
    ”; } fun.call(null,123);
    //fun.apply(null,123);谢谢@georg。这就澄清了这一点。这意味着,call()可以通过一个非原语参数作为其可选参数进行传递-我说的对吗?而非递归的深层扁平化代码-太棒了!谢谢你,朋友@Harish:添加了调用vs应用的示例