简体   繁体   English

函数参数中的数组解构

[英]Array destructuring in function parameters

I have something here related to array destructuring that I don't fully understand. 我在这里有一些与数组解构有关的东西我还不完全理解。

In the following example: 在以下示例中:

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

foo( 1, 2, 3 );

When I run this I get the following error: 当我运行这个时,我收到以下错误:

Uncaught TypeError: undefined is not a function

Now, I am not questioning the fact that this doesn't output 1, 2, 3 as one might expect since only the first value 1 actually get destructured ( a = 1[0], b = 1[1], c = 1[2] ). 现在,我并没有质疑这个事实并没有像人们预期的那样输出1, 2, 3因为只有第一个值1实际上被破坏了( a = 1[0], b = 1[1], c = 1[2] )。

But here's the thing: 但事情就是这样:

I can perfectly write 1[0], 1[1], 1[2] and I get undefined for each of those. 我可以完美地写出1[0], 1[1], 1[2]并且每个都undefined

Then why the foo function I wrote above throws an exception instead of simply returning 3 times undefined as I'd expect. 那么为什么我上面写的foo函数抛出一个异常而不是像我期望的那样简单地返回3次undefined

Indeed, if I write bar as following, I am getting 3 undefined as should happen. 实际上,如果我按照以下方式编写bar ,我将会发生3 undefined情况。

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

bar();
// undefined undefined undefined

Can someone tell me what JS does in the first foo() and why the output it's not undefined undefined undefined ? 有人能告诉我JS在第一个foo()做了什么以及为什么输出没有undefined undefined undefined

Destructuring with an array pattern uses iteration in the background, ie the value being destructured must be iterable. 使用数组模式进行的解构使用后台迭代,即被解构的值必须是可迭代的。

In fact, in Firefox, the error message seems more indicative: 实际上,在Firefox中,错误消息似乎更具说明性:

TypeError: (destructured parameter) is not iterable TypeError :(析构参数)不可迭代

That is where the comparison you make with evaluating 1[0], 1[1], 1[2] goes wrong: that does not need 1 to be iterable. 这是你在评估1[0], 1[1], 1[2]时所做的比较出错的地方:不需要1可迭代。

A more correct comparison would be to do this: 更正确的比较是这样做:

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

...and that code will fail. ......而且代码会失败。

Array destructuring is actually Iterator Destructuring that works with anything implementing Symbol.iterator method. 数组解构实际上是迭代器解构,适用于任何实现Symbol.iterator方法的东西。

For example 例如

 function foo([a, b, c]) { console.log([a, b, c]) } foo({ * [Symbol.iterator]() { yield 1; yield 2; yield 3; } }) 

Number doesn't implement iterator protocol Number不实现迭代器协议

 console.log(1[Symbol.iterator]) 

That's why you get the error. 这就是你得到错误的原因。

But if you implement it ( NOT RECOMMENDED ) 但是如果你实现它( 不推荐

 Number.prototype[Symbol.iterator] = function*() { yield * this.toString(2); // just an example } function foo([a, b,c]) { console.log(a, b, c); } foo(6) 

The function foo() is completely different with bar() due to the fact that 1 is a valid number in javascript and trying to access 1[0] is undefined as it looks for the index 0 of value 1 which is surely undefined . 函数foo()bar()完全不同,因为1是javascript中的有效数字,并且尝试访问1[0]undefined因为它查找值为1的索引0 ,这肯定是undefined That is why you get three undefined for 1[0], 1[1], 1[2] 这就是为什么你得到三个undefined1[0], 1[1], 1[2]

Now, the single undefined from foo() is not from console.log() but it is from the error 现在,来自foo()的单个undefined不是来自console.log()而是来自错误

Uncaught TypeError: undefined is not a function 未捕获的TypeError:undefined不是函数

As your function signature is incorrect. 由于您的功能签名不正确。 To use it in proper way you can use spread syntax: 要以正确的方式使用它,您可以使用扩展语法:

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

This happens because the function foo() can only accept iterables . 这是因为函数foo()只能接受iterables See the below given example: 请参阅以下给出的示例:

 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 

IMHO, spread operator is used as a gatherer in these type of scenarios like this: 恕我直言, 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 

Why foo() throws an exception? 为什么foo()会抛出异常?

That's because of incompatible parameters (b/w caller & calee) which has nothing to do with the fact that in JavaScript 1[0] is undefined . 那是因为不兼容的参数(b / w caller&calee)与JavaScript 1[0] undefined的事实无关。

It's because function foo is expecting an array/string so he can destruct it. 这是因为函数foo期望一个数组/字符串,所以他可以破坏它。

Since you're not passing anything it causes the destruction to fail, this is like doing 由于你没有传递任何东西,导致破坏失败,这就像做

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

So to avoid throwing an error, provide an array argument 因此,为避免抛出错误,请提供数组参数

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM