33

你即将使用的ES2020新功能

 4 years ago
source link: https://juejin.im/post/5de76f076fb9a0165c710049
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
2019年12月04日阅读 7509

你即将使用的ES2020新功能

JavaScript中新的强大功能:类中的私有字段,可选链,无效的合并运算符和BigInts。

作者:John Au-Yeung

翻译:疯狂的技术宅

原文:levelup.gitconnected.com/new-feature…

未经允许严禁转载

img

自 2015 年发布 ES6 以来,JavaScript 一直在快速发展,每次迭代中都会出现大量新功能。 JavaScript 语言规范的新版本每年更新一次,新语言功能建议的定稿比以往更快。这意味着新功能将以前所未有的速度被整合到现代浏览器和其他 JavaScript 运行时引擎(如 Node.js)中。

在 2019年,“Stage 3”阶段有许多新功能,这意味着它即将完成,并且已经在浏览器和 Node 中获得对这些功能的支持。如果我们想将它们用于生产环境,则可以使用 Babel 之类的东西将其转换为旧版 JavaScript,以便在需要时用于旧版浏览器(如 Internet Explorer)。

在本文中,我们研究了类中的私有字段,可选链,无效合并运算符和BigInts。

类的私有字段

最新提案之一是在类中添加私有变量的方法。我们将使用 # 符号表示类的私有变量。这样就不需要使用闭包来隐藏不想暴露给外界的私有变量。例如我们可以编写一个简单的类来增加和减少数字,请看以下代码:

class Counter {
  #x = 0;  increment() {
    this.#x++;
  }  decrement() {
    this.#x--;
  }  getNum(){
    return this.#x;
  }
}const c = new Counter();
c.increment(); 
c.increment(); 
c.decrement(); 
console.log(c.getNum());
复制代码

代码中 console.log 输出的结果是 1。 #x 是一个私有变量,无法在类外部访问。所以如果我们这样写:

console.log(c.#x);
复制代码

将会得到提示 Uncaught SyntaxError: Private field '#x'

私有变量是 JavaScript 类非常需要的功能。现在,最新版本的 Chrome 和 Node.js v12 中已提供了此功能。

可选链运算符

当前,如果要访问对象的深层嵌套属性,则必须通过很长的布尔表达式去检查每个嵌套级别中的属性。必须检查每个级别中定义的每个属性,直到所需的深度嵌套的属性为止,如下代码所示:

const obj = {
  prop1: {
    prop2: {
      prop3: {
        prop4: {
          prop5: 5
        }
      }
    }
  }
}obj.prop1 &&
  obj.prop1.prop2 &&
  obj.prop1.prop2 &&
  obj.prop1.prop2.prop3 &&
  obj.prop1.prop2.prop3.prop4 &&
  console.log(obj.prop1.prop2.prop3.prop4.prop5);
复制代码

幸运的是,上面的代码在我们想要访问的每个级别中都定义了每个属性。但是,如果在任何级别的对象中都有 undefinednull 的嵌套对象,如果不进行检查,那么的程序将会崩溃。这意味着我们必须检查每个级别,以确保当它遇到 undefinednull 对象时不会崩溃。

使用可选链运算符,只需要使用 ?. 来访问嵌套对象。而且如果碰到的是 undefinednull 属性,那么它只会返回 undefined。通过可选链,可以把上面的代码改为:

const obj = {
  prop1: {
    prop2: {
      prop3: {
        prop4: {
          prop5: 5
        }
      }
    }
  }
}console.log(obj?.prop1?.prop2?.prop3?.prop4?.prop5);
复制代码

当我们的程序执行到 undefinednull 属性时,不会崩溃,而只是返回 undefined。不幸的是,这尚未在任何浏览器中实现,所以最新版本的 Babel 来使用此功能。

空位合并运算符

来自 undefinednull 值的另一个问题是,如果我们想要的变量为 undefinednull 则必须给变量设置默认值。例如:

const y = x || 500;
复制代码

当使用 || 运算符将 x 设置为 y 时,如果 x 被定义为 undefined,我们必须设置一个默认值。运算符 || 的问题在于,所有类似于 0,false 或空字符串之类的值都将被我们不想要的默认值覆盖。

为了解决这个问题,有人提议创建一个“nullish”合并运算符,用 ?? 表示。有了它,我们仅在第一项为 nullundefined 时设置默认值。使用无效的合并运算符,以上表达式将变为:

const y = x ?? 500;
复制代码

例如有以下代码:

const x = null;
const y = x ?? 500;
console.log(y); // 500const n = 0
const m = n ?? 9000;
console.log(m) // 0
复制代码

y 将被分配的值为 500,因为 x 的值为 null。但是,由于 n 不为 nullunfined,因此 m 被赋予值为 0。如果我们使用 || 而不是 ??,那么由于 0 为假,因此将为 m 赋值 9000。

不幸的是,此功能尚未在任何浏览器或 Node.js 中实现,我们必须使用最新版本的 Babel 才能使用此功能。

BigInt

我们可以用 BigInt 对象表示大于 2^{53}-1 的整数。可以通过常规操作(例如算术运算符)进行加、减、乘、除、余数和幂等运算。它可以由数字和十六进制或二进制字符串构造。此外它还支持 AND、OR、NOT 和 XOR 之类的按位运算。唯一无效的位运算是零填充右移运算符(>>>)。

同样,一元运算符 + 也不支持 Numbers 和 BitInts 之间的加法运输。仅当所有操作数均为 BigInts 时才执行这些操作。在 JavaScript 中 BigInt 与普通数字不同。它与普通数字的区别在于,数字的末尾带有一个 n

我们可以使用 BigInt 工厂函数定义 BigInt。它有一个参数,该参数可以是整数或代表十进制整数、十六进制字或二进制的字符串。 BigInt 不能与内置 Math 对象一起使用。另外在数字与 BigInt 之间进行转换时必须小心,因为在将 BigInt 转换为数字时,BigInt 的精度可能会丢失,反之亦然。

要定义 BigInt,如果要传递的参数是整数,可以像下面的码一样:

const bigInt = BigInt(1);
console.log(bigInt);
复制代码

当我们运行到 console.log 语句时,它将输出 1n。如果想将字符串传递给工厂函数,我们可以这样写:

const bigInt = BigInt('2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222');
console.log(bigInt);
复制代码

也可以通过使用以 0x 开头的字符串将十六进制数字字符串传递给工厂函数:

const bigHex = BigInt("0x1fffffffffffff111111111");
console.log(bigHex);
复制代码

当我们在 bigHex 上运行 console.log 时,上面的代码将输出为 618970019642690073311383825n

可以传入一个以 0b 开头的二进制字符串来获取 BigInt:

const bigBin = BigInt("0b111111111111111000000000011111111111111111111111");
console.log(bigBin);
复制代码

当我们在上面运行 console.log 时,上面的代码得到的结果是 281466395164671n。如果要创建的 BigInt 超出数字类型可以接受的范围,则传递字符串会很方便。

还可以使用 BigInt 字面量去定义 BigInt 类型。方法在整数的末尾附加一个 n 字符。例如可以这样写:

const bigInt = 22222222222222222222222222222222n;
console.log(bigInt);
复制代码

然后我们将 22222222222222222222222222222222222n 作为 bigInt 进行了输出。可以像使用数字一样对 BigInts 进行算术运算,例如 +-/*等。如果我们要使用 BigInts 进行这些操作,则所有操作数都必须都是 BigInts。但是如果我们得到了带小数点的结果,则小数点以后的部分将被截断。 BigInt 是一个大整数,不能存储小数。例如在下面的例子中:

const expected = 8n / 2n;
console.log(expected) // 4n 
const rounded = 9n / 2n;
console.log(rounded) // 4n
复制代码

我们得到 expectedrounded 的值都是 4n。这是因为小数部分已从 BigInt 中删除。

比较运算符可以应用于 BigInts。操作数可以是 BigInt 或数字。例如可以将 1n1 进行比较:

1n === 1
复制代码

上面的代码将评估为 false ,因为 BigInt 和数字不是同一类型。但是,当我们用双等号替换三等号时,如下面的代码所示:

1n == 1
复制代码

上面的语句被评估为 true,因为仅比较了该值。请注意,在两个示例中,我们都将 BigInt 操作数与数字操作数混合在一起。BigInts 和数字也可以与其他运算符一起进行比较,例如以下示例:

1n < 9
// true9n > 1
// true9 > 9n
// false9n > 9
// false9n >= 9
// true
复制代码

同样,它们可以混合在一起形成一个数组并进行排序。例如:

const mixedNums = [5n, 6, -120n, 12, 24, 0, 0n];
mixedNums.sort();
console.log(mixedNums)
复制代码

现在,此功能可在最新版本的 Chrome 和 Node.js中使用。

我们可以使用 # 号来表示私有类变量。这样就不必用闭包来隐藏我们不想暴露给外界的私有变量。为了解决对象中 nullundefined 值的问题,我们提供了可选链运算符来访问属性,而无需检查每个级别可能是 null 还是 undefined。使用无效的合并运算符,我们只能为变量为 nullundefined 的情况设置默认值。使用 BigInt 对象,我们可以用 JavaScript 表示超出常规数字安全范围的大数字,并对其执行标准操作,只是小数部分将从结果中省略。

欢迎关注前端公众号:前端先锋,免费领取前端工程化实用工具包。

1

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK