• 技术文章 >web前端 >前端问答

    ecmascript有什么特性

    青灯夜游青灯夜游2022-01-05 11:13:11原创271

    ecmascript的特性有:1、class(类);2、模块化;3、箭头函数;4、模板字符串;5、解构赋值;6、延展操作符;7、Promise;8、let与const;9、指数操作符“**”;10、“async/await”等等。

    本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。

    什么是ECMAScript

    ECMAScript 是一种由 ECMA国际(前身为欧洲计算机制造商协会)通过 ECMA-262 标准化的脚本程序设计语言。

    Ecma国际(Ecma International)是一家国际性会员制度的信息和电信标准组织。1994年之前,名为欧洲计算机制造商协会(European Computer Manufacturers Association)。因为计算机的国际化,组织的标准牵涉到很多其他国家,因此组织决定改名表明其国际性。现名称已不属于首字母缩略字。

    与国家政府标准机构不同,Ecma国际是企业会员制的组织。组织的标准化过程比较商业化,自称这种营运方式减少官僚追求效果。

    其实 Ecma国际负责了很多标准的制定,比如有如下这些规范。大家可以看到这里面有我们今天的主角,ECMAScript 规范、 C#语言规范、 C++/CLI语言规范等。

    ECMAScript 和 JavaScript 的关系

    1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。

    该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

    因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。

    ES6 与 ECMAScript 2015 的关系

    ECMAScript 2015(简称 ES2015)这个词,也是经常可以看到的。它与 ES6 是什么关系呢?

    2011 年,ECMAScript 5.1 版发布后,就开始制定 6.0 版了。因此,ES6 这个词的原意,就是指 JavaScript 语言的下一个版本。

    但是,因为这个版本引入的语法功能太多,而且制定过程当中,还有很多组织和个人不断提交新功能。事情很快就变得清楚了,不可能在一个版本里面包括所有将要引入的功能。常规的做法是先发布 6.0 版,过一段时间再发 6.1 版,然后是 6.2 版、6.3 版等等。

    标准委员会最终决定,标准在每年的 6 月份正式发布一次,作为当年的正式版本。接下来的时间,就在这个版本的基础上做改动,直到下一年的 6 月份,草案就自然变成了新一年的版本。这样一来,就不需要以前的版本号了,只要用年份标记就可以了。

    因此,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。

    ECMAScript 的历史

    1996年11月,Netscape公司将Js提交给国际化标准组织ECMA,当初该语言能够成为国际化标准。
    1997年,ECMAScript 1.0版本推出。(在这年,ECMA发布262号标准文件(ECMA-262)的第一版,规定浏览器脚本语言的标准,并将这种语言称为ECMAScript,也就是ES1.0版本。)
    1998年6月,ES 2.0 版发布。
    1999年12月,ES 3.0 版发布,并成为JS的通行标准,得到广泛支持。
    2007年10月,ES 4.0 版草案发布。
    2008年7月,由于各方分歧太大,ECMA决定终止ES 4.0的开发。转而将其中涉及现有功能改善的一小部分发布为ES 3.1 。但是回后不久将其改名为ES 5.0版;
    2009年12月,ES 5.0 版正式发布。

    2011年6月,ES 5.1 版发布,并成为ISO国际标准(ISO/IEC 16262:2011)。
    2013年3月,ES 6 草案终结,并且不再添加新的功能。
    2013年12月,ES 6 草案发布。
    2015年6月,ES 6 正式版本发布。

    从此后面每年6月都会发布一个正式版本,所以目前最新的版本是2021年6月发布的ES12。

    ECMAScript各版本新增特性

    ES6新增特性

    1、class

    ES6 引入了 class(类),让 JavaScript 的面向对象编程变得更加简单和易于理解。

    class Student {
      constructor() {
        console.log("I'm a student.");
      }
     
      study() {
        console.log('study!');
      }
     
      static read() {
        console.log("Reading Now.");
      }
    }
     
    console.log(typeof Student); // function
    let stu = new Student(); // "I'm a student."
    stu.study(); // "study!"
    stu.read(); // "Reading Now."

    2、模块化

    ES5 支持原生的模块化,在ES6中模块作为重要的组成部分被添加进来。模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过 import 来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。

    export function sum(x, y) {
      return x + y;
    }
    export var pi = 3.141593;
    import * as math from "lib/math";
    alert("2π = " + math.sum(math.pi, math.pi));
    
    import {sum, pi} from "lib/math";
    alert("2π = " + sum(pi, pi));

    3、箭头函数

    =>不只是关键字 function 的简写,它还带来了其它好处。箭头函数与包围它的代码共享同一个 this,能帮你很好的解决this的指向问题。比如 var self = this;或 var that =this这种引用外围this的模式。但借助 =>,就不需要这种模式了。

    () => 1
    
    v => v+1
    
    (a,b) => a+b
    
    () => {
      alert("foo");
    }
    
    e => {
      if (e == 0){
        return 0;
      }
      return 1000/e;
    }

    4、模板字符串

    ES6 支持 模板字符串,使得字符串的拼接更加的简洁、直观。

    //不使用模板字符串
    var name = 'Your name is ' + first + ' ' + last + '.'
    //使用模板字符串
    var name = `Your name is ${first} ${last}.`

    在 ES6 中通过 ${}就可以完成字符串的拼接,只需要将变量放在大括号之中。

    5、解构赋值

    解构赋值语法是 JavaScript 的一种表达式,可以方便的从数组或者对象中快速提取值赋给定义的变量。

    // 对象
    const student = {
        name: 'Sam',
        age: 22,
        sex: '男'
    }
    // 数组
    // const student = ['Sam', 22, '男'];
    
    // ES5;
    const name = student.name;
    const age = student.age;
    const sex = student.sex;
    console.log(name + ' --- ' + age + ' --- ' + sex);
    
    // ES6
    const { name, age, sex } = student;
    console.log(name + ' --- ' + age + ' --- ' + sex);

    6、延展操作符

    延展操作符…可以在函数调用/数组构造时, 将数组表达式或者 string 在语法层面展开;还可以在构造对象时, 将对象表达式按 key-value 的方式展开。

    //在函数调用时使用延展操作符
    function sum(x, y, z) {
      return x + y + z
    }
    const numbers = [1, 2, 3]
    console.log(sum(...numbers))
    
    //数组
    const stuendts = ['Jine', 'Tom']
    const persons = ['Tony', ...stuendts, 'Aaron', 'Anna']
    conslog.log(persions)

    7、Promise

    Promise 是异步编程的一种解决方案,比传统的解决方案 callback 更加的优雅。它最早由社区提出和实现的,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。

    const getJSON = function(url) {
      const promise = new Promise(function(resolve, reject){
        const handler = function() {
          if (this.readyState !== 4) {
            return;
          }
          if (this.status === 200) {
            resolve(this.response);
          } else {
            reject(new Error(this.statusText));
          }
        };
        const client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
    
      });
    
      return promise;
    };
    
    getJSON("/posts.json").then(function(json) {
      console.log('Contents: ' + json);
    }, function(error) {
      console.error('出错了', error);
    });

    8、let 与 const

    在之前 JS 是没有块级作用域的,const与 let 填补了这方便的空白,const与 let 都是块级作用域。

    function f() {
      {
        let x;
        {
          // 正确
          const x = "sneaky";
          // 错误,常量const
          x = "foo";
        }
        // 错误,已经声明过的变量
        let x = "inner";
      }
    }

    ES7新增特性

    1、Array.prototype.includes()

    includes() 函数用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。

    [1, 2, 3].includes(-1)                   // false
    [1, 2, 3].includes(1)                    // true
    [1, 2, 3].includes(3, 4)                 // false
    [1, 2, 3].includes(3, 3)                 // false
    [1, 2, NaN].includes(NaN)                // true
    ['foo', 'bar', 'quux'].includes('foo')   // true
    ['foo', 'bar', 'quux'].includes('norf')  // false

    2、指数操作符

    在 ES7 中引入了指数运算符 **, **具有与 Math.pow(…)等效的计算结果。使用指数运算符 **,就像 +、- 等操作符一样。

    //之前的版本
    Math.pow(5, 2)
    
    // ES7
    5 ** 2
    // 5 ** 2 === 5 * 5

    ES8新增特性

    1、async/await

    异步函数返回一个AsyncFunction对象并通过事件循环异步操作。

    const resolveAfter3Seconds = function() {
      console.log('starting 3 second promsise')
      return new Promise(resolve => {
        setTimeout(function() {
          resolve(3)
          console.log('done in 3 seconds')  
        }, 3000)  
      })  
    }
    
    const resolveAfter1Second = function() {
      console.log('starting 1 second promise')
      return new Promise(resolve => {
          setTimeout(function() {
            resolve(1) 
            console.log('done, in 1 second') 
          }, 1000)
      })  
    }
    
    const sequentialStart = async function() {
      console.log('***SEQUENTIAL START***')
      const one = await resolveAfter1Second()
      const three = await resolveAfter3Seconds()
    
      console.log(one)
      console.log(three)
    }
    
    sequentialStart();

    2、Object.values()

    Object.values()是一个与 Object.keys()类似的新函数,但返回的是 Object 自身属性的所有值,不包括继承的值。

    const obj = { a: 1, b: 2, c: 3 }
    //不使用 Object.values()
    const vals = Object.keys(obj).map((key) => obj[key])
    console.log(vals)
    //使用 Object.values()
    const values = Object.values(obj1)
    console.log(values)

    从上述代码中可以看出 Object.values()为我们省去了遍历 key,并根据这些 key 获取 value 的步骤。

    3、Object.entries()

    Object.entries()函数返回一个给定对象自身可枚举属性的键值对的数组。

    //不使用 Object.entries()
    Object.keys(obj).forEach((key) => {
      console.log('key:' + key + ' value:' + obj[key])
    })
    //key:b value:2
    
    //使用 Object.entries()
    for (let [key, value] of Object.entries(obj1)) {
      console.log(`key: ${key} value:${value}`)
    }
    //key:b value:2

    4、String padding

    在 ES8 中 String 新增了两个实例函数 String.prototype.padStart和 String.prototype.padEnd,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。

    console.log('0.0'.padStart(4, '10'))
    console.log('0.0'.padStart(20))
    
    console.log('0.0'.padEnd(4, '0'))
    console.log('0.0'.padEnd(10, '0'))

    5、Object.getOwnPropertyDescriptors()

    Object.getOwnPropertyDescriptors()函数用来获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

    let myObj = {
      property1: 'foo',
      property2: 'bar',
      property3: 42,
      property4: () => console.log('prop4')  
    }
    
    Object.getOwnPropertyDescriptors(myObj)
    
    /*
    { property1: {…}, property2: {…}, property3: {…}, property4: {…} }
      property1: {value: "foo", writable: true, enumerable: true, configurable: true}
      property2: {value: "bar", writable: true, enumerable: true, configurable: true}
      property3: {value: 42, writable: true, enumerable: true, configurable: true}
      property4: {value: ƒ, writable: true, enumerable: true, configurable: true}
      __proto__: Object
    */

    ES9新增特性

    1、async iterators

    ES9 引入异步迭代器(asynchronous iterators), await可以和 for…of循环一起使用,以串行的方式运行异步操作。

    //如果在 async/await中使用循环中去调用异步函数,则不会正常执行
    async function demo(arr) {
      for (let i of arr) {
        await handleDo(i);
      }
    }
    
    //ES9
    async function demo(arr) {
      for await (let i of arr) {
        handleDo(i);
      }
    }

    2、Promise.finally()

    一个 Promise 调用链要么成功到达最后一个 .then(),要么失败触发 .catch()。在某些情况下,你想要在无论 Promise 运行成功还是失败,运行相同的代码,例如清除,删除对话,关闭数据库连接等。

    .finally()允许你指定最终的逻辑。

    function doSomething() {
      doSomething1()
        .then(doSomething2)
        .then(doSomething3)
        .catch((err) => {
          console.log(err)
        })
        .finally(() => {})
    }

    3、Rest/Spread属性

    Rest:对象解构赋值的其余属性。

    Spread:对象解构赋值的传播属性。

    //Rest
    let { fname, lname, ...rest } = { fname: "Hemanth", lname: "HM", location: "Earth", type: "Human" };
    fname; //"Hemanth"
    lname; //"HM"
    rest; // {location: "Earth", type: "Human"}
    
    //Spread
    let info = {fname, lname, ...rest};
    info; // { fname: "Hemanth", lname: "HM", location: "Earth", type: "Human" }

    ES10新增特性

    1、Array的 flat()方法和 flatMap()方法

    flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

    flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 和 深度值1的 flat 几乎相同,但 flatMap通常在合并成一种方法的效率稍微高一些。

    let arr = ['a', 'b', ['c', 'd']];
    let flattened = arr.flat();
    
    console.log(flattened);    // => ["a", "b", "c", "d"]
    
    arr = ['a', , , 'b', ['c', 'd']];
    flattened = arr.flat();
    
    console.log(flattened);    // => ["a", "b", "c", "d"]
    
    arr = [10, [20, [30]]];
    
    console.log(arr.flat());     // => [10, 20, [30]]
    console.log(arr.flat(1));    // => [10, 20, [30]]
    console.log(arr.flat(2));    // => [10, 20, 30]
    console.log(arr.flat(Infinity));    // => [10, 20, 30]

    2、String的 trimStart()方法和 trimEnd()方法

    分别去除字符串首尾空白字符

    const str = "   string   ";
    
    console.log(str.trimStart());    // => "string   "
    console.log(str.trimEnd());      // => "   string"

    3、Object.fromEntries()

    Object.entries()方法的作用是返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。

    而 Object.fromEntries() 则是 Object.entries() 的反转,Object.fromEntries() 函数传入一个键值对的列表,并返回一个带有这些键值对的新对象。

    const myArray = [['one', 1], ['two', 2], ['three', 3]];
    const obj = Object.fromEntries(myArray);
    
    console.log(obj);    // => {one: 1, two: 2, three: 3}

    ES11新增特性

    1、Promise.allSettled

    Promise.all最大问题就是如果其中某个任务出现异常(reject),所有任务都会挂掉,Promise 直接进入 reject 状态。

    Promise.allSettled在并发任务中,无论一个任务正常或者异常,都会返回对应的的状态(fulfilled 或者 rejected)与结果(业务 value 或者 拒因 reason),在 then 里面通过 filter 来过滤出想要的业务逻辑结果,这就能最大限度的保障业务当前状态的可访问性。

    const promise1 = Promise.resolve(3);
    const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
    const promises = [promise1, promise2];
    
    Promise.allSettled(promises).
      then((results) => results.forEach((result) => console.log(result.status)));
    
    // expected output:
    // "fulfilled"
    // "rejected"

    2、String.prototype.matchAll

    matchAll() 方法返回一个包含所有匹配正则表达式及分组捕获结果的迭代器。 在 matchAll出现之前,通过在循环中调用 regexp.exec来获取所有匹配项信息(regexp需使用 /g 标志)。如果使用 matchAll,就可以不必使用 while 循环加 exec 方式(且正则表达式需使用/g标志)。使用 matchAll会得到一个迭代器的返回值,配合 for…of, array spread, or Array.from() 可以更方便实现功能。

    const regexp = /t(e)(st(\d?))/g;
    const str = 'test1test2';
    
    const array = [...str.matchAll(regexp)];
    
    console.log(array[0]);
    // expected output: Array ["test1", "e", "st1", "1"]
    
    console.log(array[1]);
    // expected output: Array ["test2", "e", "st2", "2"]

    ES12新增特性

    1、Promise.any

    Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise。

    const promise1 = new Promise((resolve, reject) => reject('我是失败的Promise_1'));
    const promise2 = new Promise((resolve, reject) => reject('我是失败的Promise_2'));
    const promiseList = [promise1, promise2];
    Promise.any(promiseList)
    .then(values=>{
      console.log(values);
    })
    .catch(e=>{
      console.log(e);
    });

    2、逻辑运算符和赋值表达式

    逻辑运算符和赋值表达式,新特性结合了逻辑运算符(&&=,||=,??=)。

    a ||= b
    //等价于
    a = a || (a = b)
    
    a &&= b
    //等价于
    a = a && (a = b)
    
    a ??= b
    //等价于
    a = a ?? (a = b)

    3、replaceAll

    返回一个全新的字符串,所有符合匹配规则的字符都将被替换掉。

    const str = 'hello world';
    str.replaceAll('l', ''); // "heo word"

    4、数字分隔符

    数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性。

    const money = 1_000_000_000;
    //等价于
    const money = 1000000000;
    
    1_000_000_000 === 1000000000; // true

    【相关推荐:javascript学习教程

    以上就是ecmascript有什么特性的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:JavaScript ecmascript
    上一篇:ecmascript是解释器吗 下一篇:javascript中hover的用法是什么
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【腾讯云】年中优惠,「专享618元」优惠券!• JavaScript定位元素的方法有哪些• JavaScript怎样实现点击出现效果• JavaScript中wrap的意思是什么• 深入聊聊JavaScript中的JSON模块• javascript中怎么将一维数组转为三维数组?方法介绍• 一文带你搞懂JavaScript中的原型和原型链
    1/1

    PHP中文网