这种默认参数和解构的特殊场景是如何工作的?

How does this particular scenario of default params and destructuring work?

我今天尝试了一些事情,遇到了一个我想了解的行为。

var b = ({a = 1, b = 1, c = 1}) => a + b + c;

b(); // throws error.

但是如果这样定义的话

var b = ({a = 1, b = 1, c = 1} = 0) => a + b + c;

b() // returns 3
b([]) // returns 3

这应该不是错误吧?零不知何故成为了这里的一个对象吗?它在某种程度上等同于以下内容吗?

var b = ({a = 1, b = 1, c = 1} = {}) => a + b + c; // this is possible I guess.

我的问题不是常规解构和默认参数如何工作,而是如何评估这个特定场景。

有人能给我解释一下吗?

它采用原始值的原型并将其用作解构值。

var b = ({ a = 1, b = 1, c = 1, toFixed } = 0) => toFixed.bind(a + b + c)(2);

console.log(b());

var b = ({a=1,b=1,c=1})=>a+b+c
b() //throws error.

它希望有一些参数作为输入传递,而不是你调用 b() 而不传递任何东西。

var b = ({a=1,b=1,c=1} = 0)=>a+b+c 
b() //return 3

之所以有效,是因为您已为其分配了一个初始值 {a=1,b=1,c=1} = 0,即 0,并且它正在创建您使用的默认 a+b+c 的 3 个变量值 = 1

解构对数组和对象都有效。 根据我在对象模式重构

中的发现

The object pattern coerces destructuring sources to objects before accessing properties

例如

const {length : len} = 'abc'; // len = 3
const {toString: s} = 123; // s = Number.prototype.toString

你的情况:

b([]) // return 3 as it arrays destructing
b({a=1,b=2,c=3} =0) // works because of object coercion

请查看此 link 了解更多信息。

原因: 在 JavaScript 中,编译器进行自动类型转换,因此 0 被视为 'Object(0)',因为函数 b 需要对象作为输入。

更多详情: 函数 b 通过对象析构将输入作为默认值为 a、b、c 的对象。

所以 b 的调用者必须传递一个对象,如果没有传递任何东西就会抛出错误。 当某些东西被传递给 b 时,它会尝试从传递的对象中提取 a、b、c 值。如果传递了某些东西,它会采用这些值,如果没有传递任何东西,则默认为定义

中给出的值

例如,如果你传递这样的东西 b({a : 10, b: 20}) 它默认 c 值为 1 并打印 31

对于b({a : 10, d: 20}),b和c变为默认值,returns 12

希望这有助于理解。

({a = 1, b = 1, c = 1} = something) => {}

只是表示something必须是一个对象或可以转换为一个对象,即它不能是nullundefined1

因此,在 0 的情况下,它会继续获取 0abc 属性,即 (0).a(0).b(0).c,都是undefined,因此它们都默认为1,它们提供的默认值。

0 当然可以强制转换为 Number 对象。这就是为什么你可以做 (0).toString(){toString} = 0。这正是这里发生的事情。

它通常不等同于使用 {} 作为默认值,因为这将使用空对象的属性(包括自己的属性和原型链上的属性),而不是数字的属性。


1: 这种“结构验证”的最简化形式是({} = something)。对于数组的解构,它是 ([] = something),这意味着 something 也必须是 iterable。顺便说一句,那些空的解构赋值不会创建任何变量,它们只是进行结构检查。