ES2020有哪些值得关注的新特性?(翻译)

原文地址:https://alligator.io/js/es2020/?luicode=10000011&lfid=1076031400854834&u=https%3A%2F%2Fallitator.io%2Fjs%2Fes2020%2F 作者:Joshua Hall

JavaScript经过近几年的快速发展和更新,现在是时候来梳理一下最新的ES2020的重大更新了。在本文中,我们将讨论一些伴随ES2020到来的最新的最重大的JS新特性。

初始化

由于用户都比较懒,他们甚至都不愿意升级一下自己的浏览器来使程序员的开发工作更简单一些,因此程序员不得不使用babel工具来将一些新的JS特性兼容到较低版本的不支持新特性的用户浏览器中。出于最简单的目的,我在此使用Parcel bundle工具包来使程序尽可能快的运行。在命令行界面输入如下命令:

$yarn add parcel-bundle

在package.json文件中增加如下属性:

"scripts": {
    "start" : "parcel index.html"
},

很不幸,由于目前我们的开发环境中还没有关于ES2020的相关预设,因此这样的写法大大的超出了当前的版本,还不能直接这样使用。我们需要将一些预设添加到.babelrc文件中保存,之后Parcel就会将我们所有想要的都初始化。.babelrc中添加的设置如下:

{
    "plugins" : [
        "@babel/plugin-proposal-nullish-coalescing-operator",
        "@babel/plugin-proposal-optional-chaining",
        "@babel/plugin-proposal-class-properties",
        "@babel/plugin-proposal-private-methods",
        "@babel/plugin-syntax-bigint"
    ]
}

准备工作就绪,那么下面就让我们看看ES2020为我们准备啥新奇有趣的新特性吧!

类的私有变量

类的一个主要作用就是将我们的代码进行封装以便在不同的模块中进行调用。当需要在不同的地方调用相同的功能时,我们就需要考虑将该功能封装成一个类,而不是将所有的东西都做成全局的以方便调用,这样容易引起代码混乱。现在,通过在变量或者方法前面增加一个简单的哈希符号我们就能限制类的变量或者方法只能在类的内部进行调用。代码如下:

class Message{
    #message = "Howdy"
    greet() { console.log(this.#message) }
}
const greeting = new Message()
greeting.greet() //Howdy
console.log(greeting.#message) //Private name #message is not defined

Promise.allSettled

在实际开发中,当我们使用多个promise时,尤其是当多个promise之间还相互依赖时,我们就需要记录它们之间究竟发生了什么以便更好地进行代码调试和纠错。通过使用Promise.allSettled,我们会创建一个新的promise,这个promise只有在所有的和它相关promise都完成的时候才会返回。它允许我们访问一个数组以提供所有已经完成promise的相关数据。代码如下:

const p1 = new Promise((res, rej) => setTimeout(res, 1000));
const p2 = new Promise((res, rej) => setTimeout(rej, 1000));
Promise.allSettled([p1, p2]).then(data => console.log(data));
/*打印
[
    Object { status: "fulfilled", value: undefined},
    Object { status: "rejected", value: undefined}
]
*/

空值合并符

由于JavaScript是动态类型,因此当我们定义变量的时候时刻都要在心里记住该值是真值还是假值。很多时候,我们会定义一个拥有多个值的对象,有时候我们需要允许一些技术层面的假值存在,比如空字符串或者数字0。设置默认值有一个不好的地方,就是它很容易受到干扰,被非法数值重写掉。请看下面代码:

let person = {
    profile: {
        name: "",
        age: 0
    }
};
console.log(person.profile.name || "Anonymous");
console.log(person.profile.age || 18);

相对于双竖杠符号来说,双问号操作符具有更严格的类型检查,它只允许值为null或者undefined的时候才会使用默认值。0或者空字符串都不会使用默认值。如下面代码所示:

console.log(person.profile.name ?? "Anonymous"); //""
console.log(person.profile.age ?? 18)  //0

可选链式操作符

和空值合并符的情况一样,当JavaScript遇到假值的情况时不会不会表现得向我们预想得那样。当遇到一个undefined的变量时,我们可以返回一个默认值,但是如果如果我们的访问路径本身就一个undefined时,我们该怎么办呢?
通过在点号前面添加一个问号标记,我们就能确保不管路径中任何部分是undefined,我们都能正确优雅地处理它。代码如下:

let person = {};
console.log(person.profile.name ?? "Anonymous"); //person.profile is undefined
console.log(person?.profile?.name ?? "Anonymous"); //Anonymous
console.log(person?.profile?.age ?? 18); //18

BigInt

我们在这里并不讨论具体的技术细节。但是考虑到JavaScript处理数字的方式,当出现一些不确定的因素时,就会涉及到一些更高级的技术细节。JavaScript所能处理的最大数字时2^53,我们可以通过MAX_SOFE_INTEGER进行查看。代码如下:

const max= Number.MAX_SAFE_INTEGER;
console.log(max); //9007199254740991

上述代码没有什么问题,但是接下来,事情就变得有点奇怪了。请看下面的代码:

console.log(max + 1); //9007199254740992
console.log(max + 2); //9007199254740992
console.log(max + 3); //9007199254740994
console.log(Math.pow(2, 53) == Math(2, 53) + 1); //true

我们可以将上述代码用BitInt进行实现。通过将字符n置于算术表达式后面,我们就能使用和计算真正变态级大数值。由于我们不能混淆普通的数值和BitInt数值,因此所有关于数值计算的的函数都需要以BigInt的类型再实现一遍。参考如下代码:

const bigNum = 1000000000000000000000000000000n;
console.log(bigNum * 2n); //2000000000000000000000000000000n

动态Import

如果一个件中有大量的的公共函数,实际上它们中的一部分又很少用到,那么所有对于该文件的引用就会造成大量的资源浪费。现在,我们通过使用async/await来动态引入那些我们需要调用的资源,以减少资源引入的浪费。
提示:目前我们的Parcel设置还不支持该功能,我们需要切换到Node.js环境中。
请看下面代码:

math.js
const add= (num1, num2) => num1 + num2;
export { add };

index.js
const doMath = async (num1, num2) +> {
    if (num1 && num2){
        const math = await import('./math.js');
        console.log(math.add(5, 10));
    };
};
doMath(4, 2);

总结

现在,你大概已经为JavaScript的这些新特性感到不可思议了,与此同时你的同事可能还因为不够了解而对这些特性感到常困惑。(当然,除非他们已经看过了本人写的这篇文章,嘿嘿。。)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容