es6/es7/es8常用新特性总结(超实用)

小编 2026-06-26 阅读:236 评论:0
  本文标题有误导性,因为我其实想写node8的新特性,说实话一下子从node v1.x跳跃到n...

  本文标题有误导性,因为我其实想写node8的新特性,说实话一下子从node v1.x跳跃到node 8.x+ 真有点受宠若惊的感觉。一直觉得node 数组、 对象、序列等的处理没有python方便,因为需要借助外部的一些包比如underscore /lodash才能实现,但是接下来是见证奇迹的时刻,es6/7/8让node代码变的更简洁、更易懂。

  Node.js的优点之一就是前后端用同一种语言,本质上还是js,因此可以通过babel来使nodejs支持对应的ECMAScript。

目录

  • 如何让Nodejs支持对应的ES
  • ES6常用新特性
    • let && const
    • iterable类型
    • 解构赋值
    • =>函数
    • ...操作符
  • ES7新特性
    • Array.prototype.includes
    • Exponentiation Operator(求幂运算)
  • ES8新特性
    • Object.values/Object.entries
    • String padding(字符串填充)
    • Object.getOwnPropertyDescriptors
    • 函数参数列表和调用中的尾逗号(Trailing commas)
    • 异步函数(Async Functions)

如何让Nodejs支持对应的ES

  不同版本的Node.js对Babel有不同的支持,如若是Nodejs支持ES6语法,需要引入babel。因此要安装一些babel的依赖包,如babel-preset-es2015 / babel-core /babel-cli。

ES6对应es2015,ES7对应es2016,ES8对应es2017,同时对应支持的node版本更高

检测ES6

可以使用es-checker来检测当前Node.js对ES6的支持情况,全局安装es-checker

$ npm install -g es-checker

安装好之后,执行以下命令来查看Node.js对ES6的支持情况:

$ es-checker

可以从输出中查看当前版本Node.js(v7.7.4)对ES6的支持情况:

es6/es7/es8常用新特性总结(超实用)es6/es7/es8常用新特性总结(超实用)
$ es-checkerECMAScript 6 Feature Detection (v1.4.1)Variables  √ let and const  √ TDZ error for too-early access of let or const declarations  √ Redefinition of const declarations not allowed  √ destructuring assignments/declarations for arrays and objects  √ ... operatorData Types  √ For...of loop  √ Map, Set, WeakMap, WeakSet  √ Symbol  √ Symbols cannot be implicitly coercedNumber  √ Octal (e.g. 0o1 ) and binary (e.g. 0b10 ) literal forms  √ Old octal literal invalid now (e.g. 01 )  √ Static functions added to Math (e.g. Math.hypot(), Math.acosh(), Math.imul() )  √ Static functions added to Number (Number.isNaN(), Number.isInteger() )String  √ Methods added to String.prototype (String.prototype.includes(), String.prototype.repeat() )  √ Unicode code-point escape form in string literals (e.g. u{20BB7} )  √ Unicode code-point escape form in identifier names (e.g. var u{20BB7} = 42; )  √ Unicode code-point escape form in regular expressions (e.g. var regexp = /u{20BB7}/u; )  √ y flag for sticky regular expressions (e.g. /b/y )  √ Template String LiteralsFunction  √ arrow function  √ default function parameter values  √ destructuring for function parameters  √ Inferences for function name property for anonymous functions  × Tail-call optimization for function calls and recursionArray  × Methods added to Array.prototype ([].fill(), [].find(), [].findIndex(), [].entries(), [].keys(), [].values() )  √ Static functions added to Array (Array.from(), Array.of() )  √ TypedArrays like Uint8Array, ArrayBuffer, Int8Array(), Int32Array(), Float64Array()  √ Some Array methods (e.g. Int8Array.prototype.slice(), Int8Array.prototype.join(), Int8Array.prototype.forEach() ) added to the TypedArray prototypes  √ Some Array statics (e.g. Uint32Array.from(), Uint32Array.of() ) added to the TypedArray constructorsObject  √ __proto__ in object literal definition sets [[Prototype]] link  √ Static functions added to Object (Object.getOwnPropertySymbols(), Object.assign() )  √ Object Literal Computed Property  √ Object Literal Property Shorthands  √ Proxies  √ ReflectGenerator and Promise  √ Generator function  √ PromisesClass  √ Class  √ super allowed in object methods  √ class ABC extends Array { .. }Module  × Module export command  × Module import command=========================================Passes 38 feature DetectionsYour runtime supports 90% of ECMAScript 6=========================================
View Code

添加es6支持

全局安装babel-cli, 项目安装 babel-preset-es2015:

npm install babel-cli -gnpm install babel-preset-es2015 --save

安装完之后,还需要添加一个名为.babelrc的配置文件。方便babel-cli使用babel-preset-es2015。文件内容如下:

{  "presets": ["es2015"],  "plugins": [    "add-module-exports"  ]}

或者在项目入口文件(如app.js)引用下babel:

require('babel-register')({    presets: ['es2015']});

如此,再也不会报如下的错误:

import a from './config';^^^^^^SyntaxError: Unexpected token import

并且也会支持ES6的新特性。上述是描述node如何支持ES6的,支持ES8是类似的,preset指定 "presets": ["es2017"]即可。

下面进入正题,到底ES6~8有哪些实用的新特性呢

ES6常用新特性

let && const 

let 命令也用于变量声明,但是作用域为局部

{    let a = 10;    var b = 1;        }

在函数外部可以获取到b,获取不到a,因此例如for循环计数器就适合使用let。

const用于声明一个常量,设定后值不会再改变

const PI = 3.1415;PI // 3.1415PI = 3; //TypeError: Assignment to constant variable.

iterable类型

为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型,具有iterable类型的集合可以通过新的for … of循环来遍历。

var a = ['A', 'B', 'C'];var s = new Set(['A', 'B', 'C']);var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);for (var x of a) { // 遍历Array    alert(x);}for (var x of s) { // 遍历Set    alert(x);}for (var x of m) { // 遍历Map    alert(x[0] + '=' + x[1]);}

Map相关操作如下, Set同理:

var m = new Map(); // 空Mapm.set('Adam', 67); // 添加新的key-valuem.set('Bob', 59);m.has('Adam'); // 是否存在key 'Adam': truem.get('Adam'); // 67m.delete('Adam'); // 删除key 'Adam'm.get('Adam'); // undefined

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。 
例如数组:

let [a, b, c] = [1, 2, 3];//等同于let a = 1;let b = 2;let c = 3;

这真的让代码看起来更优美,有种python赋值的既视感。 

对象的解构赋值:获取对象的多个属性并且使用一条语句将它们赋给多个变量。

var {  StyleSheet,  Text,  View} = React;等同于var StyleSheet = React.StyleSheet;var Text = React.Text;var View = React.Text;

箭头函数

ES6中新增箭头操作符用于简化函数的写法,操作符左边为参数,右边为具体操作和返回值。

var sum = (num1, num2) => { return num1 + num2; }//等同于var sum = function(num1, num2) {    return num1 + num2;};

箭头函数还修复了this的指向,使其永远指向词法作用域:

var obj = {    birth: 1990,    getAge: function () {        var b = this.birth; // 1990        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象        return fn();    }};obj.getAge(); // 25

...操作符

这个的引入几乎不会用到extend这个函数来。通过它可以将数组作为参数直接传入函数:

var people=['Wayou','John','Sherlock'];function sayHello(people1,people2,people3){    console.log(`Hello ${people1},${people2},${people3}`);}//改写为sayHello(...people);//输出:Hello Wayou,John,Sherlock 

在函数定义时可以通过…rest获取定义参数外的所有参数(类似C#中的参数数组,可以有任意多个参数):

function foo(a, b, ...rest) {    console.log('a = ' + a);    console.log('b = ' + b);    console.log(rest);}foo(1, 2, 3, 4, 5);// 结果:// a = 1// b = 2// Array [ 3, 4, 5 ]

这个真是完美!关于更多...的说明参考这篇博客

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类,与多数传统语言类似。

//定义类class Point {  constructor(x, y) {    this.x = x;    this.y = y;  }  toString() {    return '(' + this.x + ', ' + this.y + ')';  }}

ES7新特性

Array.prototype.includes

  Array.prototype.includes用法都容易和简单。它是一个替代indexOf,开发人员用来检查数组中是否存在值,indexOf是一种尴尬的使用,因为它返回一个元素在数组中的位置或者-1当这样的元素不能被找到的情况下。所以它返回一个数字,而不是一个布尔值。开发人员需要实施额外的检查。在ES6,要检查是否存在值你需要做一些如下图所示小技巧,因为他们没有匹配到值,Array.prototype.indexOf返回-1变成了true(转换成true),但是当匹配的元素为0位置时候,该数组包含元素,却变成了false。
let arr = ['react', 'angular', 'vue']// WRONGif (arr.indexOf('react')) { // 0 -> evaluates to false, definitely as we expected  console.log('Can use React') // this line would never be executed}// Correctif (arr.indexOf('react') !== -1) {  console.log('Can use React')}

或者使用一点点hack 位运算符 ~ 使代码更加紧凑一些,因为~(位异或)对任何数字相当于-(a + 1):

let arr = ['react', 'angular', 'vue']// Correctif (~arr.indexOf('react')) {  console.log('Can use React')}

在ES7中使用includes代码如下:

let arr = ['react', 'angular', 'vue']// Correctif (arr.includes('react')) {  console.log('Can use React')}

还能在字符串中使用includes:

let str = 'React Quickly'// Correctif (str.toLowerCase().includes('react')) {  // true  console.log('Found "react"')  }

除了增强了可读性语义化,实际上给开发者返回布尔值,而不是匹配的位置。

includes也可以在NaN(非数字)使用。最后 ,includes第二可选参数fromIndex,这对于优化是有好处的,因为它允许从特定位置开始寻找匹配。
更多例子:

console.log([1, 2, 3].includes(2)) // === true)console.log([1, 2, 3].includes(4)) // === false)console.log([1, 2, NaN].includes(NaN)) // === true)console.log([1, 2, -0].includes(+0)) // === true)console.log([1, 2, +0].includes(-0)) // === true)console.log(['a', 'b', 'c'].includes('a')) // === true)console.log(['a', 'b', 'c'].includes('a', 1)) // === false)

总而言之,includes在一个数组或者列表中检查是否存在一个值,给任何开发人员带来简单性。

Exponentiation Operator(求幂运算)

  求幂运算大多数是做一些数学计算,对于3D,VR,SVG还有数据可视化非常有用。在ES6或者早些版本,不得不创建一个循环,创建一个递归函数或者使用Math.pow,如果忘记了什么是指数,当你有相同数字(基数)自相相乘多次(指数)。例如,7的3次方是7*7*7

所以在ES6/2015ES,你能使用Math.pow创建一个短的递归箭头函数:

calculateExponent = (base, exponent) => base*((--exponent>1)?calculateExponent(base, exponent):base)console.log(calculateExponent(7,12) === Math.pow(7,12)) // trueconsole.log(calculateExponent(2,7) === Math.pow(2,7)) // true

现在在ES7 /ES2016,以数学向导的开发者可以使用更短的语法:

let a = 7 ** 12let b = 2 ** 7console.log(a === Math.pow(7,12)) // trueconsole.log(b === Math.pow(2,7)) // true

开发者还可以操作结果:

let a = 7a **= 12let b = 2b **= 7console.log(a === Math.pow(7,12)) // trueconsole.log(b === Math.pow(2,7)) // true

许多ES新特性是从其他语言(CoffeeScript,Ruby,python等)模仿而来的

ES8新特性

Object.values/Object.entries

  Object.values和 Object.entries是在ES2017规格中,它和Object.keys类似,返回数组类型,其序号和Object.keys序号对应。类似python中的dict.iteritems()。

Object.values,Object.entriesObject.keys各自项返回是数组,相对应包括key,value或者可枚举特定对象property/attribute

在ES8 /ES2017之前,Javascript开发者需要迭代一个对象的自身属性时候不得不用Object.keys,通过迭代且使用obj[key]获取value值返回一个数组,很挫的:

let obj = {a: 1, b: 2, c: 3}Object.keys(obj).forEach((key, index)=>{  console.log(key, obj[key])})

而使用ES6/ES2015 中for/of稍微好点:

let obj = {a: 1, b: 2, c: 3}for (let key of Object.keys(obj)) {  console.log(key, obj[key])}

Object.values返回对象自身可以迭代属性值(values)为数组类型。我们最好使用Array.prototype.forEach迭代它,结合ES6的箭头函数隐形返回值:

let obj = {a: 1, b: 2, c: 3}Object.values(obj).forEach(value=>console.log(value)) // 1, 2, 3

或者实用for/of:

let obj = {a: 1, b: 2, c: 3}for (let value of Object.values(obj)) {  console.log(value)}// 1, 2, 3

·Object.entries·,在另一方面,将会返回对象自身可迭代属性key-value对数组(作为一个数组),他们(key-value)分别以数组存放数组中:

let obj = {a: 1, b: 2, c: 3}JSON.stringify(Object.entries(obj))"[["a",1],["b",2],["c",3]]"

可以使用ES6/ES2015解构,从这嵌套数组中分别声明key和value

let obj = {a: 1, b: 2, c: 3}Object.entries(obj).forEach(([key, value]) => { console.log(`${key} is ${value}`)})// a is 1, b is 2, c is 3

同样使用ES6for/of(毕竟全部都是数组)遍历Object.entries返回来的结果值:

let obj = {a: 1, b: 2, c: 3}for (let [key, value] of Object.entries(obj)) {  console.log(`${key} is ${value}`)}// a is 1, b is 2, c is 3

现在从对象中提取values和key-value pairs 变得非常容易了。Object.valuesObject.entries这种方式不想之前 Object.keys(自身属性key+顺序相同)结合for/of(ES6)一起,我们不仅仅可以提取他们还可以迭代他们。

String padding(字符串填充)

String.prototype.padStartString.prototype.padEnd在javascript字符操作是一个不错的体验,帮助避免依赖而外的库。
padStart()在开始部位填充,返回一个给出长度的字符串,填充物给定字符串,把字符串填充到期望的长度。从字符串的左边开始(至少大部分西方语言),一个经典例子是使用空格创建列:
console.log('react'.padStart(10).length)         // "       react" is 10console.log('backbone'.padStart(10).length)         // "  backbone" is 10

它对于财务方面非常有用:

console.log('0.00'.padStart(20))            console.log('10,000.00'.padStart(20))    console.log('250,000.00'.padStart(20)) 

如果是为会计做账之类的,这个很实用,帐做的很整齐

         0.00    10,000.00   250,000.00    

第二个参数,让我们放一些其他的填充字符替代空字符串,一个字符串填充:

console.log('react'.padStart(10, '_'))         // "_____react"console.log('backbone'.padStart(10, '*'))         // "**backbone"

padEnd顾名思义就是从字符串的尾端右边开始填充。第二个参数,你能实际上用一个任何长度的字符串。例如:

console.log('react'.padEnd(10, ':-)'))         // "react:-):-" is 10console.log('backbone'.padEnd(10, '*'))         // "backbone**" is 10

再赏几个例子作为总结:

// String.prototype.padStart(targetLength [, padString])'hello'.padStart(10); // '     hello''hello'.padStart(10, '0'); // '00000hello''hello'.padStart(); // 'hello''hello'.padStart(6, '123'); // '1hello''hello'.padStart(3); // 'hello''hello'.padStart(3, '123'); // 'hello';// String.prototype.padEnd(targetLength [, padString])'hello'.padEnd(10); // 'hello     ''hello'.padEnd(10, '0'); // 'hello00000''hello'.padEnd(); // 'hello''hello'.padEnd(6, '123'); // 'hello1''hello'.padEnd(3); // 'hello''hello'.padEnd(3, '123'); // 'hello';

Object.getOwnPropertyDescriptors

  这新的 Object.getOwnPropertyDescriptors返回对象obj所有自身属性描述。这是一个多参数版本的Object.getOwnPropertyDescriptors(obj,propName)将会返回obj中propName属性的一个单独描述。
在我们日常不可变编程(immutable programming)时代中,有了这个方法很方便(记住,Javascript中对象是引用传递)在ES5中,开发者要使用Object.assign()来拷贝对象, Object.assign()分配属性只有copy和定义新的属性。当我们使用更加复杂对象和类原型,这可能会出问题。
Object.getOwnPropertyDescriptors允许创建真实的对象浅副本并创建子类,它通过给开发者描述符来做到这一点.在Object.create(prototype, object)放入描述符后,返回一个真正的浅拷贝。
Object.create(  Object.getPrototypeOf(obj),  Object.getOwnPropertyDescriptors(obj))

或者可以合并两个对象targetsource如下:

Object.defineProperties(  target,  Object.getOwnPropertyDescriptors(source))

以上是Object.getOwnPropertyDesciptors用法。但是什么是描述符(descriptor)呢?就是一个对象的描述。

这里有两种描述符号类型:
1.数据描述符(Data descriptor)
2.存取器描述符(Accessor descriptor)
存取描述符有必须属性:get 或者set或者get和set两个就是如你所想的getter和setter函数,然后存取描述符还有可选属性configurableenumerable
let azatsBooks = {    books: ['React Quickly'],  get latest () {    let numberOfBooks = this.books.length    if (numberOfBooks == 0) return undefined    return this.books[numberOfBooks - 1]  }}

这个例子数据描述符booksObject.getOwnPropertyDescriptor(azatsBooks, 'books')产生结果如下:

Object    configurable: true    enumerable: true    value: Array[1]    writable: true    __proto__: Object

同样的,Object.getOwnPropertyDescriptor(azatsBooks, 'latest')将会展现latest的描述符,这个latest(get)存取器描述符展现如下:

Object    configurable: truee    numerable: true    get: latest()    set: undefined    __proto__: Object

现在我们调用新方法获取所有的描述符:

console.log(Object.getOwnPropertyDescriptors(azatsBooks))

它会给出这个对象两个描述符books和latest:

Object  books: Object    configurable: true    enumerable: true    value: Array[1]    writable: true    __proto__: Object  latest: Object    configurable: true    enumerable: true    get: latest()    set: undefined    __proto__: Object  __proto__: Object

函数参数列表和调用中的尾逗号(Trailing commas)

尾逗号在函数定义中只是一个纯粹语法变化,在ES5中,将会非法语法,在函数参数后面应该是没有逗号的:

var f = function(a,  b,  c,  d) { // NO COMMA!  // ...  console.log(d)}f(1,2,3,'this')

在ES8中,这种尾逗号是没有问题的:

var f = function(a,  b,  c,  d,) { // COMMA? OK!  // ...  console.log(d)}f(1,2,3,'this')
var arr = [1,  // Length == 3  2,  3,]  // <--- oklet obj = {a: 1,  // Only 3 properties  b: 2,  c: 3,}  // <--- ok

尾逗号主要有用在使用多行参数风格(典型的是那些很长的参数名),开发者终于可以忘记逗号放在第一位这种奇怪的写法。自从逗号bugs主要原因就是使用他们。而现在你可以到处使用逗号,甚至最后参数都可以。

异步函数(Async Functions)

  异步函数(或者async/await)特性操作是Promise最重要的功能。这种想法是为了在写异步代码中简化它,因为人类大脑最讨厌这种平行非序号思维了。它只是不会演变这种方式。本来以为Promise的到来已经是摆脱node异步的福音了,在ES8,异步函数是那么给力。开发者定义一个asyc函数里面不包含或者包含await 基于Promise异步操作。在这引擎之下一个异步函数返回一个Promise,无论无何你在任何地方不会看到这样的一个词Promise。
例如,在ES6中我们可以使用Promise,Axios库向GraphQL服务器发送一个请求:
axios.get(`/q?query=${query}`)  .then(response => response.data)  .then(data => {    this.props.processfetchedData(data) // Defined somewhere else  })  .catch(error => console.log(error))

任何一个Promise库都能兼容新的异步函数,我们可以使用同步try/catch做错误处理

async fetchData(url) => {  try {    const response = await axios.get(`/q?query=${query}`)    const data = response.data    this.props.processfetchedData(data)  } catch (error) {    console.log(error)  }}

异步函数返回一个Promise,所以我们像下面可以继续执行流程:

async fetchData(query) => {  try {    const response = await axios.get(`/q?query=${query}`)    const data = response.data    return data  } catch (error) {    console.log(error)  }}fetchData(query).then(data => {  this.props.processfetchedData(data)})

有了 async/await,我们的代码执行异步看起来像执行同步一样。可以从头到尾读起来非常简单和易懂,因为出现结果顺序和函数题中从头到尾顺序一样啊!

最后让我以一幅图(此图笑喷我)结束今天的博客,今天是端午放假前,我还在这么认真的拼命的写博客,哈哈哈

es6/es7/es8常用新特性总结(超实用)

 reference:

 https://node.university/blog/498412/es7-es8-post

 

作者:zhoujie
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,不然我担心博客园找你算账
如果您觉得本文对你有帮助,请竖起您的大拇指右下角点推荐,也可以关注我
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表