函数参数中的数组解构

时间:2018-07-13 13:34:37

标签: javascript arrays function

我这里有一些我不完全了解的与数组解构有关的东西。

在以下示例中:

function foo( [a, b, c] ) {
    console.log(a, b, c)
}

foo( 1, 2, 3 );

运行此命令时,出现以下错误:

Uncaught TypeError: undefined is not a function

现在,我没有质疑这样的事实,即它不会像预期的那样输出1, 2, 3,因为只有第一个值1实际上被解构了(a = 1[0], b = 1[1], c = 1[2])。

但是这是东西:

我可以完美地写1[0], 1[1], 1[2],而我每个人都得到undefined

然后为什么我上面编写的foo函数会引发异常,而不是像我期望的那样简单地返回3次undefined

实际上,如果我按如下方式编写bar,则我应该得到3 undefined

function bar() {
    console.log( 1[0], 1[1], 1[2] )
}

bar();
// undefined undefined undefined

有人可以告诉我JS在第一个foo()中做什么,为什么它的输出不是undefined undefined undefined

5 个答案:

答案 0 :(得分:3)

使用数组模式进行解构会在后台使用迭代,即要解构的值必须是可迭代的。

事实上,在Firefox中,错误消息似乎更具指示性:

  

TypeError :(结构化参数)不可迭代

这就是您在评估1[0], 1[1], 1[2]时所做的比较错误的地方:不需要1是可迭代的。

更正确的比较是这样做:

console.log([...1]);
// or:
const [a, b, c] = 1;

...并且该代码将失败。

答案 1 :(得分:1)

数组解构实际上是Iterator Destructuring,可以与实现Symbol.iterator方法的任何东西一起使用。

例如

function foo([a, b, c]) {
  console.log([a, b, c])
}

foo({
  * [Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
})

Number未实现迭代器协议

console.log(1[Symbol.iterator])

这就是为什么您会收到错误消息。

但是,如果您实施它(不推荐

Number.prototype[Symbol.iterator] = function*() {
  yield * this.toString(2); // just an example
}

function foo([a, b,c]) {
  console.log(a, b, c);
}

foo(6)

答案 2 :(得分:0)

函数foo()bar()完全不同,原因是1是JavaScript中的有效数字,而尝试访问1[0]的原因是undefined因为它会寻找值0的索引1,该索引肯定是undefined。这就是为什么您为undefined获得三个1[0], 1[1], 1[2]

现在,undefined中的单个foo()不是来自console.log(),而是来自错误

  

未捕获的TypeError:未定义不是函数

由于您的功能签名不正确。要以正确的方式使用它,可以使用传播语法:

function foo(...arg) {
    console.log(arg[0], arg[1], arg[2]);
}

foo( 1, 2, 3 );

答案 3 :(得分:0)

之所以会这样,是因为函数foo()只接受iterables。参见下面的示例:

function foo( [a, b, c] ) {
    console.log(a, b, c)
}

foo( [4, 5, 6] );  // works okay

foo( 3,4,5 ); // undefined is not a function

恕我直言,spread operator在此类情况下用作收集器:

function foo( ...[a, b, c] ) {
    console.log(a, b, c)
}

foo( ...[4, 5, 'v'] );  //works fine

foo(1,3,4); // also works fine

  

为什么foo()抛出异常?

这是因为参数不兼容(黑白呼叫者和calee),与JavaScript 1[0]中的undefined无关。

答案 4 :(得分:0)

这是因为函数foo期望一个数组/字符串,以便他可以破坏它。

由于您没有传递任何东西,因此会导致破坏失败,就像这样做

var arrayVariable = undefined
var [a, b, c] = arrayVariable // this will throw an error
var d = arrayVariable['a'] // this will throw an error

为避免引发错误,请提供一个数组参数

foo('') // undefined, undefined, undefined
foo('123') // 1, 2, 3
foo([]); // undefined, undefined, undefined
foo([1, 2, 3]) // 1, 2, 3