在使用 ES6 的解构语法时,我们经常会用到默认值,以防止在解构数组或对象时出现未定义的情况。然而,在使用多重默认值时,很可能会遇到一些奇怪的问题。
问题描述
考虑下面的示例代码:
-- -------------------- ---- ------- ----- --- - - ---- - ---- -- - -- ----- ----- ---- - -- - --- - ---- ----------------- -- --- --
在这个示例中,我们希望从 obj
中获取一个名为 foo
的属性,并从该属性中获取一个名为 bar
的子属性。如果 foo
或 bar
不存在,则使用默认值。因此,我们使用了多重默认值来实现这个目标。
然而,如果我们把 obj
改成如下所示:
const obj = { foo: null };
那么当我们使用上述代码时,bar
的值将不再是我们期望的 1
,而是 undefined
。这是为什么呢?
问题分析
让我们来逐步分析这个问题。首先,我们需要理解如何使用默认值来定义一个解构模式:
const {prop = defaultValue} = object;
这段代码的意思是,如果 object
中的 prop
属性不存在,或者其值为 undefined
,则使用 defaultValue
作为 prop
的值。否则,使用 object[prop]
的值作为 prop
的值。
例如,考虑下面的代码:
const obj = {foo: undefined}; const {foo = 42} = obj; console.log(foo); // 输出: 42
由于 foo
的值为 undefined
,因此使用了默认值 42
。但是,如果我们使用如下代码:
const obj = {}; const {foo = 42} = obj; console.log(foo); // 输出: 42
由于 foo
属性不存在,因此也使用了默认值 42
。
接下来,我们回到原始问题中。当我们使用如下代码时:
const {foo: {bar = 1} = {}} = obj;
实际上,它相当于:
const tmp = obj.foo === undefined ? {} : obj.foo; const {bar = 1} = tmp;
也就是说,如果 obj.foo
不存在,则使用一个空对象作为默认值。然后,我们使用默认值 1
来定义 bar
属性。因此,当 obj.foo
不存在时,bar
的值将为 1
。
但是,当 obj.foo
的值为 null
时,它并不是一个空对象,因此默认值 1
并不会生效。我们得到了 undefined
。
解决方案
为了解决这个问题,我们需要将解构模式改成如下形式:
const {foo: {bar = 1} = {bar: 1}} = obj;
这里,我们使用了另一个对象 {bar: 1}
作为默认值。如果 obj.foo
不存在,则默认值 {bar: 1}
会被使用。否则,我们会从 obj.foo
中获取 bar
属性的值。
这个默认值对象可以包含多个属性,例如:
const {foo: {bar = 1, baz = 2} = {bar: 1, baz: 2}} = obj;
结论
在使用多重默认值的情况下,我们需要注意使用默认值的对象的值是否符合我们的预期。如果使用一个空对象作为默认值无法满足要求,我们可以使用一个带有合适属性的默认值对象来解决这个问题。
希望这篇文章对解决 ES6 解构数组与对象多重默认值的 Bug 有所帮助,也希望大家能够在日常开发中避免类似的问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670792f9d91dce0dc86a5654