Photo by James Harrison on Unsplash
这里 2021 JS 新特性指的是 2021 年,我个人接触到的 JS 新特性。不代表该特性是 2021 年才有的。
动态 import
这里就不再赘述动态 import
的具体相关内容了,有需要的可以直接查看 MDN 中相关的讲解。
- Chrome 支持版本 63+
Demo
<button>dynamic import</button>
<script>
const button = document.querySelector('button')
button.addEventListener('click', async function (){
const fnc = await import('./alert.js')
fnc.message()
})
</script>
export function message () {
alert('Great!')
}
Logical AND assignment
逻辑与
赋值符(x &&= y
) 只有在 x
是 truthy 的情况下,才会赋值。
- chrome 支持版本 85+
Demo
let a = 1;
let b = 0;
a &&= 2;
console.log(a);
// expected output: 2
b &&= 2;
console.log(b);
// expected output: 0
短路计算
逻辑与
运算符是从左向右进行计算的,其短路规则如下:
对于表达式:(some falsy expression) && expr
来说,短路意味着 js 不会对 expr
部分进行运算求值。因此不会产生副作用(例如,如果 expr
是一个函数调用, 那么此时该函数将不会调用)。
逻辑与
赋值符的短路意味着 x &&= y
等同于 x && (x = y)
。
可选链操作符
可选链操作符( ?.
)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?.
操作符的功能类似于 .
链式操作符,不同之处在于,在引用为空(nullish ) (null
或者 undefined
) 的情况下不会引起错误,该表达式短路返回值是 undefined
。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined
。
当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。
- chrome 支持版本 80+
Demo
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined
console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined
短路计算
当在表达式中使用可选链时,如果左操作数是 null
或 undefined
,表达式将不会被计算,例如:
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // x 将不会被递增,依旧输出 0
连用可选链操作符
let customer = {
name: "Carl",
details: {
age: 82,
location: "Paradise Falls" // details 的 address 属性未有定义
}
};
let customerCity = customer.details?.address?.city;
// … 可选链也可以和函数调用一起使用
let duration = vacations.trip?.getTime?.();
类私有域
类属性在默认情况下是公有
的,但可以使用增加哈希前缀 #
的方法来定义私有类字段,这一隐秘封装的类特性由 JavaScript 自身强制执行。
这些私有域包括:私有实例字段,私有静态字段,私有实例方法和私有静态方法。具体描述可参考 MDN 。
- chrome 支持版本 84+
空值合并运算符
空值合并操作符( ??
)是一个逻辑操作符,当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。
与逻辑或操作符(||
)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 ||
来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,''
或 0
)时。见下面的例子。
const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"
const baz = 0 ?? 42;
console.log(baz);
// expected output: 0
- chrome 支持版本 80+
短路
与 OR 和 AND 逻辑操作符相似,当左表达式不为 null
或 undefined
时,不会对右表达式进行求值。
function A() { console.log('函数 A 被调用了'); return undefined; }
function B() { console.log('函数 B 被调用了'); return false; }
function C() { console.log('函数 C 被调用了'); return "foo"; }
console.log( A() ?? C() );
// 依次打印 "函数 A 被调用了"、"函数 C 被调用了"、"foo"
// A() 返回了 undefined,所以操作符两边的表达式都被执行了
console.log( B() ?? C() );
// 依次打印 "函数 B 被调用了"、"false"
// B() 返回了 false(既不是 null 也不是 undefined)
// 所以右侧表达式没有被执行
不能与 AND 或 OR 操作符共用
将 ??
直接与 AND(&&
)和 OR(||
)操作符组合使用是不可取的。这种情况下会抛出 SyntaxError
。
null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError
但是,如果使用括号来显式表明运算优先级,是没有问题的:
(null || undefined ) ?? "foo"; // 返回 "foo"