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

9
我今天尝试了一些东西,发现了一个我想要理解的行为。
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.

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

有人能为我解释一下吗?

5个回答

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

这里的意思是something必须是一个对象或可以转换为对象,也就是说不能为nullundefined. 1 因此,在0的情况下,它会获取0abc属性,即(0).a(0).b(0).c,它们都是undefined,因此所有这些属性默认为提供的默认值1
当然,0可以强制转换为Number对象。这就是为什么你可以执行(0).toString(){toString} = 0。这正是这里发生的事情。
通常,这不等同于使用{}作为默认值,因为这将使用空对象的属性(自有属性和原型链上的属性),而不是数字的属性。
1:这个“结构验证”的最简形式是({} = something)。对于数组解构,它是([] = something),意味着something也必须是可迭代的。顺便说一下,这些空解构赋值不会创建任何变量,它们只进行结构检查。

只要默认值可以被强制转换为对象,那么传递什么都无所谓,对吗? - Shyam Babu
任何非 null 或 undefined 的值都可以使用。例如:var f = ({toFixed=null} = 0)=>typeof toFixed;f(); 将打印出 "function" 而不是 null。 - FINDarkside
@ShyamBabu 是的,调用该函数而不带参数,或者使用 undefinednull 作为参数都可以工作,但你也应该问问自己,0 是否是一个合理的默认值。 - Sebastian Simon
0不是明智的,我同意,只是对这种行为感到好奇。那么在数组解构的情况下,这也是行为吗?转换为数组? - Shyam Babu
在数组解构的情况下,something 也必须是可迭代的。数组、映射、集合、argumentsHTMLCollection 等都可以工作,但其他非可迭代值将失败。除此之外,它的工作方式相同。 - Sebastian Simon

1
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,并且它正在创建使用默认值=1的3个变量a+b+c。

0

析构函数适用于数组和对象。从我在对象模式重构中发现的情况来看,对象模式会将析构源强制转换为对象,然后再访问属性。

例如:

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

请查看此 链接 以获取更多信息。

0

原因:在JavaScript中,编译器会自动进行类型转换,所以0被视为'Object(0)',因为函数b期望输入对象。

更多细节: 函数b采用对象解构的默认值a、b、c作为输入。

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

例如,如果您传递像这样的内容b({a : 10, b: 20}),它将默认c值为1并打印31

对于b({a : 10, d: 20}),b和c变成默认值,并返回12

希望这有助于理解。


-1

它使用原始值的原型作为解构值。

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

console.log(b());


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接