在ES12(ECMAScript 2021)中,新增了一个Logical nullish assignment运算符(??=),它是nullish合并运算符(??)和赋值运算符(=)的结合体,用于给变量赋值时判断其左侧是否为null或undefined,如果是则进行赋值操作,否则不做任何操作。这个运算符的出现大大简化了我们的代码,但是也存在一些问题,本文将对它的问题及解决方式进行详细讲解。
问题一:与||或&&语法混用时出现的问题
以下是一个常见的使用Logical nullish assignment运算符的例子:
let foo; foo ??= 'bar';
上面的代码会先检查foo的值是否为null或undefined,如果是则将其赋值为'bar',否则不做任何操作。这个例子很简单,但是我们在与||或&&语法混用时可能会出现一些问题。
例如,我们想要给foo赋一个“假”的初始值,然后再通过Logical nullish assignment运算符给它赋值,代码如下:
let foo = false; foo ||= 'bar'; foo ??= 'baz'; console.log(foo); // false
我们可以看到,这里的逻辑是先判断foo是否为“真”,如果是则不赋值,否则给它赋值为'bar',最后再用Logical nullish assignment运算符将其赋值为'baz'。但是,我们期望的结果是'baz',而不是false。这是因为||运算符在判断为“假”值时会将右侧的值赋给变量,而不是判断其为null或undefined,而Logical nullish assignment运算符会判断其左侧是否为null或undefined,如果不是则不会赋值。
解决该问题的方式是使用括号明确表达式的优先级,将问题代码改为:
let foo = false; (foo ||= 'bar') ??= 'baz'; console.log(foo); // 'baz'
使用括号可以明确表达式的优先级,保证Logical nullish assignment运算符先执行,这样就能得到我们期望的结果。
问题二:不支持在对象字面量或数组字面量中使用
另一个问题是,Logical nullish assignment运算符不支持在对象字面量或数组字面量中使用。例如,我们想要定义一个对象,其属性默认值为null,然后使用Logical nullish assignment运算符给它赋值,代码如下:
const obj = { foo ??= 'bar', baz: null, }; console.log(obj); // 'Uncaught SyntaxError: Unexpected token '??=''
我们会发现,该代码会抛出一个语法错误,因为对象字面量中不支持使用该运算符。
同样,以下是一个在数组字面量中使用Logical nullish assignment运算符的例子:
const arr = [ foo ??= 'bar', null, ]; console.log(arr); // 'Uncaught SyntaxError: Unexpected token '??=''
该代码同样会抛出一个语法错误,因为数组字面量中也不支持使用该运算符。
解决该问题的方式是将对象字面量或数组字面量定义好后再使用Logical nullish assignment运算符给其属性或元素赋值:
对象字面量:
const obj = { baz: null, }; obj.foo ??= 'bar'; console.log(obj); // { foo: 'bar', baz: null }
数组字面量:
const arr = [ null, null, ]; arr[0] ??= 'bar'; console.log(arr); // [ 'bar', null ]
这样就可以避免出现语法错误。
结论
ES12中的Logical nullish assignment运算符虽然为我们的代码带来了许多便利,但是在使用中需要注意与||或&&语法混用时的优先级问题以及不支持在对象字面量或数组字面量中使用的问题。我们需要注意这些问题,根据实际需求进行代码编写,以避免出现不必要的错误。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/673933e7317fbffedf159fb3