最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

ES10 特性的完整指南小结

来源:动视网 责编:小采 时间:2020-11-27 22:00:23
文档

ES10 特性的完整指南小结

ES10 特性的完整指南小结:本篇文章主要介绍了ES10 特性的完整指南,分享给大家,具体如下: ES10 还只是一个草案。但是除了 Object.fromEntries 之外,Chrome 的大多数功能都已经实现了,为什么不早点开始探索呢?当所有浏览器都开始支持它时,你将走在前面,这只是时间问题。 在
推荐度:
导读ES10 特性的完整指南小结:本篇文章主要介绍了ES10 特性的完整指南,分享给大家,具体如下: ES10 还只是一个草案。但是除了 Object.fromEntries 之外,Chrome 的大多数功能都已经实现了,为什么不早点开始探索呢?当所有浏览器都开始支持它时,你将走在前面,这只是时间问题。 在


但奇怪的是:

如果你从这个正则表达式中删除 /g,你将永远在第一个结果上创建一个无限循环。这在过去是一个巨大的痛苦。想象一下,从某个数据库接收正则表达式时,你不确定它的末尾是否有 /g,你得先检查一下。

使用 .matchAll() 的好理由

  • 在与捕获组一起使用时,它可以更加优雅,捕获组只是使用 () 提取模式的正则表达式的一部分。
  • 它返回一个迭代器而不是一个数组,迭代器本身是有用的。
  • 迭代器可以使用扩展运算符 (…) 转换为数组。
  • 它避免了带有 /g 标志的正则表达式,当从数据库或外部源检索未知正则表达式并与陈旧的RegEx 对象一起使用时,它非常有用。
  • 使用 RegEx 对象创建的正则表达式不能使用点 (.) 操作符链接。
  • 高级: RegEx 对象更改跟踪最后匹配位置的内部 .lastindex 属性,这在复杂的情况下会造成严重破坏。
  • .matchAll() 是如何工作的?

    让我们尝试匹配单词 hello 中字母 el 的所有实例, 因为返回了迭代器,所以可以使用 for…of 循环遍历它:

    // Match all occurrences of the letters: "e" or "l" 
    let iterator = "hello".matchAll(/[el]/);
    for (const match of iterator)
     console.log(match);

    这一次你可以跳过 /g, .matchall 方法不需要它,结果如下:

    [ 'e', index: 1, input: 'hello' ] // Iteration 1
    [ 'l', index: 2, input: 'hello' ] // Iteration 2
    [ 'l', index: 3, input: 'hello' ] // Iteration 3

    使用 .matchAll() 捕获组示例:

    .matchAll 具有上面列出的所有好处。它是一个迭代器,可以用 for…of 循环遍历它,这就是整个语法的不同。

    const string = 'black*raven lime*parrot white*seagull';
    const regex = /(?<color>.*?)\*(?<bird>[a-z0-9]+)/;
    for (const match of string.matchAll(regex)) {
     let value = match[0];
     let index = match.index;
     let input = match.input;
     console.log(`${value} at ${index} with '${input}'`);
    console.log(match.groups.color);
     console.log(match.groups.bird);
    }

    请注意已经没有 /g 标志,因为 .matchAll() 已经包含了它,打印如下:

    black*raven at 0 with 'black*raven lime*parrot white*seagull'
    black
    raven
    lime*parrot at 11 with 'black*raven lime*parrot white*seagull'
    lime
    parrot
    white*seagull at 23 with 'black*raven lime*parrot white*seagull'
    white
    seagull

    也许在美学上它与原始正则表达式非常相似,执行while循环实现。但是如前所述,由于上面提到的许多原因,这是更好的方法,移除 /g 不会导致无限循环。

    动态导入

    现在可以将导入分配给变量:

    element.addEventListener('click', async() => {
     const module = await import(`./api-scripts/button-click.js`);
     module.clickEvent();
    })
    

    Array.flat()

    扁平化数组:

    let multi = [1,2,3,[4,5,6,[7,8,9,[10,11,12]]]];
    multi.flat(); // [1,2,3,4,5,6,Array(4)]
    multi.flat().flat(); // [1,2,3,4,5,6,7,8,9,Array(3)]
    multi.flat().flat().flat(); // [1,2,3,4,5,6,7,8,9,10,11,12]
    multi.flat(Infinity); // [1,2,3,4,5,6,7,8,9,10,11,12]

    Array.flatMap()

    let array = [1, 2, 3, 4, 5];
    array.map(x => [x, x * 2]);
    
    
    let array = [1, 2, 3, 4, 5];
    array.map(x => [x, x * 2]);

    结果:

    [Array(2), Array(2), Array(2), Array(2), Array(2)]
    0: (2) [1, 2]
    1: (2) [2, 4]
    2: (2) [3, 6]
    3: (2) [4, 8]
    4: (2) [5, 10]

    使用 flatMap 方法:

    array.flatMap(v => [v, v * 2]);
    [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
    

    Object.fromEntries()

    将键值对列表转换为对象:

    let obj = { apple : 10, orange : 20, banana : 30 };
    let entries = Object.entries(obj);
    entries;
    (3) [Array(2), Array(2), Array(2)]
     0: (2) ["apple", 10]
     1: (2) ["orange", 20]
     2: (2) ["banana", 30]
    let fromEntries = Object.fromEntries(entries);
    { apple: 10, orange: 20, banana: 30 }

    String.trimStart() 与 String.trimEnd()

    let greeting = " Space around ";
    greeting.trimEnd(); // " Space around";
    greeting.trimStart(); // "Space around ";
    

    格式良好的 JSON.stringify()

    此更新修复了字符 U+D800 到 U+DFFF 的处理,有时可以进入 JSON 字符串。 这可能是一个问题,因为 JSON.stringify 可能会将这些数字格式化为没有等效 UTF-8 字符的值, 但 JSON 格式需要 UTF-8 编码。

    解析方法使用格式良好的JSON字符串,如:

    '{ “prop1” : 1, "prop2" : 2 }'; // A well-formed JSON format string

    注意,要创建正确 JSON 格式的字符串,绝对需要在属性名周围加上双引号。缺少或任何其他类型的引号都不会生成格式良好的JSON。

    '{ “prop1” : 1, "meth" : () => {}}'; // Not JSON format string

    JSON 字符串格式与 Object Literal 不同,后者看起来几乎一样,但可以使用任何类型的引号括住属性名,也可以包含方法(JSON格式不允许使用方法):

    let object_literal = { property: 1, meth: () => {} };

    不管怎样,一切似乎都很好。第一个示例看起来是兼容的。但它们也是简单的例子,大多数情况下都能顺利地工作!

    U+2028 和 U+2029 字符

    问题是, ES10 之前的 EcmaScript 实际上并不完全支持 JSON 格式。前 ES10 时代不接受未转义行分隔符 U+2028 和段落分隔符 U+2029 字符:

    对于 U+D800 - U+DFFF 之间的所有字符也是如此

    如果这些字符潜入 JSON 格式的字符串(假设来自数据库记录),你可能会花费数小时试图弄清楚为什么程序的其余部分会产生解析错误。

    因此,如果你传递 eval 这样的字符串 “console.log(' hello ')”,它将执行 JavaScript语句 (通过尝试将字符串转换为实际代码),也类似于 JSON.parse 将处理你的 JSON 字符串的方式。

    稳定的 Array.prototype.sort()

    V8 之前的实现对包含10个以上项的数组使用了一种不稳定的快速排序算法。

    一个稳定的排序算法是当两个键值相等的对象在排序后的输出中出现的顺序与在未排序的输入中出现的顺序相同时。

    但情况不再是这样了,ES10 提供了一个稳定的数组排序:

    var fruit = [
     { name: "Apple", count: 13, },
     { name: "Pear", count: 12, },
     { name: "Banana", count: 12, },
     { name: "Strawberry", count: 11, },
     { name: "Cherry", count: 11, },
     { name: "Blackberry", count: 10, },
     { name: "Pineapple", count: 10, }
    ];
    // 创建排序函数:
    let my_sort = (a, b) => a.count - b.count;
    // 执行稳定的ES10排序:
    let sorted = fruit.sort(my_sort);
    console.log(sorted);

    控制台输出(项目以相反的顺序出现):

    新的Function.toString()

    函数是对象,并且每个对象都有一个 .toString() 方法,因为它最初存在于Object.prototype.toString() 上。 所有对象(包括函数)都是通过基于原型的类继承从它继承的。

    这意味着我们以前已经有 funcion.toString() 方法了。

    但是 ES10 进一步尝试标准化所有对象和内置函数的字符串表示。 以下是各种新案例:

    典型的例子:

    function () { console.log('Hello there.'); }.toString();

    控制台输出(函数体的字符串格式:)

    ⇨ function () { console.log('Hello there.'); }

    下面是剩下的例子:

    直接在方法名 .toString()

    Number.parseInt.toString();
    ⇨ function parseInt() { [native code] }

    绑定上下文:

    function () { }.bind(0).toString();
    ⇨ function () { [native code] }
    

    内置可调用函数对象:

    Symbol.toString();
    ⇨ function Symbol() { [native code] }

    动态生成的函数:

    function* () { }.toString();
    ⇨ function* () { }

    prototype.toString

    Function.prototype.toString.call({});
    ⇨ Function.prototype.toString requires that 'this' be a Function"

    可选的 Catch Binding

    在过去,try/catch 语句中的 catch 语句需要一个变量。 try/catch 语句帮助捕获终端级别的错误:

    try {
     // Call a non-existing function undefined_Function
     undefined_Function("I'm trying");
    }
    catch(error) {
     // Display the error if statements inside try above fail
     console.log( error ); // undefined_Function is undefined
    }

    在某些情况下,所需的错误变量是未使用的:

    try {
     JSON.parse(text); // <--- this will fail with "text not defined"
     return true; <--- exit without error even if there is one
    }
    catch (redundant_sometmes) <--- this makes error variable redundant
    {
     return false;
    }

    编写此代码的人通过尝试强制 true 退出 try 子句。但是,这并不是实际发生的情况

    (() => {
     try {
     JSON.parse(text)
     return true
     } catch(err) {
     return false
     }
    })()
    => false

    在 ES10 中,捕获错误的变量是可选的

    现在可以跳过错误变量:

    try {
     JSON.parse(text);
     return true;
    }
    catch
    {
     return false;
    }

    目前还无法测试上一个示例中的 try 语句的结果,但一旦它出来,我将更新这部分。

    标准化 globalThis 对象

    这在ES10之前, globalThis 还没有标准化。

    在产品代码中,你可以自己编写这个怪物,在多个平台上“标准化”它:

    var getGlobal = function () {
     if (typeof self !== 'undefined') { return self; }
     if (typeof window !== 'undefined') { return window; }
     if (typeof global !== 'undefined') { return global; }
     throw new Error('unable to locate global object');
    };

    但即使这样也不总是奏效。因此,ES10 添加了 globalThis 对象,从现在开始,该对象用于在任何平台上访问全局作用域:

    // 访问全局数组构造函数
    globalThis.Array(0, 1, 2);
    ⇨ [0, 1, 2]
    
    // 类似于 ES5 之前的 window.v = { flag: true }
    globalThis.v = { flag: true };
    
    console.log(globalThis.v);
    ⇨ { flag: true }

    Symbol.description

    description 是一个只读属性,它返回 Symbol 对象的可选描述。

    let mySymbol = 'My Symbol';
    let symObj = Symbol(mySymbol);
    symObj; // Symbol(My Symbol)
    symObj.description; // "My Symbol"

    Hashbang 语法

    也就是 unix 用户熟悉的 shebang。它指定一个解释器(什么将执行JavaScript文件?)。

    ES10标准化,我不会对此进行详细介绍,因为从技术上讲,这并不是一个真正的语言特性,但它基本上统一了 JavaScript 在服务器端的执行方式。

    $ ./index.js

    代替

    $ node index.js

    ES10类:private、static 和 公共成员

    新的语法字符 #octothorpe(hash tag)现在用于直接在类主体的范围内定义变量,函数,getter 和 setter ......以及构造函数和类方法。

    下面是一个毫无意义的例子,它只关注新语法:

    class Raven extends Bird {
    #state = { eggs: 10};
    // getter
     get #eggs() { 
     return state.eggs;
     }
    // setter
     set #eggs(value) {
     this.#state.eggs = value;
     }
    #lay() {
     this.#eggs++;
     }
    constructor() {
     super();
     this.#lay.bind(this);
     }
    #render() {
     /* paint UI */
     }
    }

    老实说,我认为这会让语言更难读。

    代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

    文档

    ES10 特性的完整指南小结

    ES10 特性的完整指南小结:本篇文章主要介绍了ES10 特性的完整指南,分享给大家,具体如下: ES10 还只是一个草案。但是除了 Object.fromEntries 之外,Chrome 的大多数功能都已经实现了,为什么不早点开始探索呢?当所有浏览器都开始支持它时,你将走在前面,这只是时间问题。 在
    推荐度:
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top