ES7 遇到的箭头函数 BUG:解构参数默认值不生效,如何解决?

在 ES6 中,我们引入了解构赋值和默认值的语法,使得我们可以更加方便地处理函数的参数。然而,在使用箭头函数时,我们可能会遇到一个奇怪的 BUG:解构参数默认值不生效。本文将介绍这个问题的原因,并提供解决方案。

问题描述

假设我们有一个函数,它接受一个对象参数,并使用解构赋值和默认值来处理参数:

function foo({ x = 0, y = 0 } = {}) {
  console.log(x, y);
}

现在我们想将这个函数改为箭头函数:

const foo = ({ x = 0, y = 0 } = {}) => {
  console.log(x, y);
}

然而,当我们调用这个箭头函数时,传入空对象作为参数时,我们会发现默认值没有生效:

foo({}); // 无输出

这是一个非常奇怪的 BUG,让我们看看它的原因是什么。

原因分析

这个 BUG 的原因是箭头函数的参数列表有一个特殊的行为:如果参数列表为空,则表示函数没有参数。因此,当我们传入空对象时,它会被视为没有参数,而不是一个带有空对象参数的函数调用。因此,当我们使用默认值时,它不会生效。

这个问题可以通过一个简单的例子来说明:

const foo = (x = 0) => {
  console.log(x);
}

foo(); // 0
foo(undefined); // 0
foo({}); // {}

我们可以看到,当我们传入 undefined 时,参数 x 使用了默认值。但是,当我们传入空对象时,参数 x 变成了空对象。这是因为空对象被视为一个参数,而不是 undefined。

解决方案

为了解决这个问题,我们需要使用一个技巧:将参数列表改为一个数组,然后使用解构赋值来获取参数。这样,当我们传入空对象时,它被视为一个带有一个空数组参数的函数调用。因此,我们的默认值可以正常工作。

const foo = ([{ x = 0, y = 0 } = {}] = []) => {
  console.log(x, y);
}

foo(); // 0 0
foo(undefined); // 0 0
foo([{}]); // 0 0
foo([{ x: 1 }]); // 1 0
foo([{ y: 2 }]); // 0 2

我们可以看到,现在我们的默认值可以正常工作了。此外,我们还可以传入一个包含一个空对象的数组,以便传递空对象作为参数。

总结

在使用箭头函数时,我们可能会遇到一个奇怪的 BUG:解构参数默认值不生效。这是因为箭头函数的参数列表有一个特殊的行为:如果参数列表为空,则表示函数没有参数。为了解决这个问题,我们可以使用一个技巧:将参数列表改为一个数组,然后使用解构赋值来获取参数。这样,我们的默认值可以正常工作。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65bf450aadd4f0e0ff8ce24e