我这里有一些我不完全了解的与数组解构有关的东西。
在以下示例中:
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
?
答案 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