乐趣区

关于前端:细数各版本JS的新特性

ES2015(ES6)

2015JS 倒退的黄金时间,委员会提出的 ES6ES5的根底上减少了大量的新个性。
上面是 ES6 的次要更新

  • let、const 关键字
  • 箭头函数
  • class 类
  • 模块(import/export)
  • 模板语法
  • 函数参数默认值
  • rest 参数
  • 数组 / 对象 解构
  • Promise

Let/Const

ES6减少了 let/const 关键字用于解决原来只有函数作用域的问题,例如以下:

{
  let a = 10;
  const b = 10;
  var c = 20;
  a = 20;
  b = 30; // Assignment to constant variable
}
a // a is not defined
c // 20

箭头函数

ES5 中,咱们须要以上面形式定义函数

function sum(value1, value2) {return value1 + value2}

然而在箭头函数中能够写更少的代码,如下:

const sum = (value1, value2) => {return value1 + value2;}

class 类

ES5 中咱们是通过原型的形式定义一个类,在 ES6 中能够通过 class 的形式来申明一个类。
上面是 ES5 用于创立构造函数的形式

function Calcutor(moneyBeforeDiscount) {this.moneyBeforeDiscount = moneyBeforeDiscount;}

Calcutor.prototype.moneyAfterDiscount = function (discountRate) {return this.moneyBeforeDiscount * (100-discountRate)/100;
}
const demo = new Calcutor(5000)
console.log(demo.moneyAfterDiscount()); // 4000

上面是 ES6 的形式创立类

class Calculator{constructor(moneyBeforeDiscount){this.moneyBeforeDiscount = moneyBeforeDiscount;}
    moneyAfterDiscount(discountRate){return this.moneyBeforeDiscount * (100-discountRate)/100;
    }
}
const demo = new Calculator(5000);
console.log(demo.moneyAfterDiscount()); // 4000

模块(import/export)

ES6 之前,js 没有原生的模块治理形式。在 ES6 中,咱们在文件中导出函数和和变量,而后在另外一个文件引入他们。
如下:

// calculator.js
const add = (a, b) => a +b
const multiply = (a, b) => a + b

export {add, multiply}

// App.js
import {add} from './calculator'

console.log(add(2, 3))

模板语法

ES6 之前,咱们如果须要在把字符串和变量进行拼接,须要向以下的形式进行书写

const count = 3;
const str = 'count:' + count;

这种形式相当繁琐,于是 ES6 引入了模板字符串解决下面这个问题

const count = 3;
const str = `count: ${count}`

此外也能够在 ${} 写一些简略的逻辑,如下:

const count = 3;
const str = `count: ${count + 2}`

函数参数默认值

ES6 之前不能间接指定函数参数的默认值,只能应用变通的办法:

function log(x, y) {if (typeof y === 'undefined') {y = 'World';}
  console.log(x, y)
})

ES6容许为函数的参数设置默认值,即间接写在参数定义的前面

function log(x, y = 'world') {console.log(x, y)
}

rest 参数

ES6引入了 rest 参数,用于获取函数的多余参数,这样就不须要应用 arguments 对象了。
这是 ES6 之前的获取多余参数的写法

function getParams() {return Array.prototype.slice.call(arguments)
}

应用 ES6 的语法

function getParams(...params) {return params;}

数组和对象解构扩大

对象和数组的解构通常用于须要从数组或者对象中拿到某个属性值。
数组解构,let/const前面跟上一堆用中括号 [] 包裹的变量列表,变量的值为对应地位上的数组元素的值,如下:

const [a, b] = [1, 2]
console.log(a, b) // 1, 2

对象解构就是找到对象对应的属性值而后赋值给变量,如下:

const {x, y} = {x: 1, y: 2}
console.log(x, y) // 1, 2

Promise

Promise通常用于解决例如 http 申请或者耗费大量工夫的程序。Promise能够将后果传递给 then 函数,then函数处理结果会返回一个 Promise,持续调用then 进行处理结果,如果抛出谬误,能够应用 catch 进行捕捉

fetch('/')
  .then(response => response.json())
  .then(result => {console.log(result)
  })

ES2016(ES7)

ES7ES6 的根底上次要扩大了一些数组的办法例如.includes(),还有指数运算符**

Array.includes()

const number = [1, 2, 3]
console.log(number.includes(1)); // true
console.log(number.includes(7)); //false

指数运算符

console.log(2** 3)

ES2017(ES8)

ES8增加了关键字 async/await,让解决异步程序更加不便。咱们可能通过应用它防止面条代码,进步异步代码的可读性
上面是 ES6 的异步形式

fetch('/')
  .then(response => {response.json()
  })
  .then(result => {console.log(result)
  })

应用 ES8,先给函数增加关键字async,而后在异步代码前增加await,异步代码会block 整个 js 线程,只有异步代码返回后果当前,js才会继续执行,下面代码能够改成以下模式

async function fn() {const response = await fetch('/');
  const result = await response.json();
  console.log(result);
}

ES2018(ES9)

ES9没有减少新的货色,然而加强了 rest 和扩大运算符。

rest 运算符

咱们在对象属性上应用rest。他简化了从对象中抽取某个属性,残余属性赋值给另外一个对象的过程,如下:

const options = {
  enabled: true,
  text: 'Hello',
  color: 'red'
}
const {enabled, ...others} = options;
console.log(enabled) // true
console.log(others) // {text: 'Hello', color: 'red'}

对象的扩大符

在对象后面加扩大运算符...,就会浅浅拷贝以后对象的属性值赋值给新对象

const options = {text: 'Hello'}
const param = {enabled: true, ...options}
console.log(param) // {enabled: true, text: 'Hello',}

ES2019(ES10)

ES10让应用 try/catch 更加简略,不须要申明一个 Error 而后去捕捉他。
以下是以前的状况,catch须要一个 error 参数

// before
try {fetch('/')
} catch (error) {console.log(error)
}

之后 catch 中的 error 是可选的,这对不须要晓得抛出的谬误是什么的场景可能有些帮忙

try {fetch('/')
} catch {// 解决你的逻辑}

ES2020(ES11)

ES11减少一些新个性

  • 动静引入
  • BigInt
  • 空值合并运算符
  • 可选链

动静引入

ES6 当咱们须要引入资源须要在文件结尾中央中央应用import,这是一种动态的引入形式。动静引入解决的问题就是可能资源太多包体积太大,有些资源能够通过动静引入的形式进行缩小包体积,具体如下:

let stageId = 'A'
let stage

if (stageId === 'A') {stage = await import('./stages/A')
} else {stage = await import('./stages/B')
}

stage.run();

BigInt

JsNumber 类型只能平安的示意 -(2^53-1)2^53-1范的值,即 Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER,超出这个范畴的整数计算或者示意会失落精度。
创立一个 BigInt 类型能够应用一下两种形式:

const big = 12344n

const alsoBig = BigInt(20)

管制合并运算符

在获取变量值的时候,通常为了防止为 null 或未定义,通常须要提供默认值。目前,在 JavaScript 中表白这种用意的一种典型办法是应用 || 操作符

const score = null;
console.log(score || 'no-score') // no-score

这对于 null 或者 undefined 值的罕用状况是可行的,然而存在很多变量并不是 null 或者undefined,然而取到了一个默认值,如下:

const score = 0;
console.log(score || 'no-score') // no-score

此时打印的后果依然是 no-score,应用 ES11 的形式就能够防止后面不是undefined 或者 null 然而布尔值是 false 的状况如下:

const score = 0;
console.log(score ?? 'no-score') // 0

可选链

如果有以下一个对象,属性嵌套很深

const student ={
        profile:{
            school:{name:'RUPP'}
        }
    }

当咱们须要获取这个 name 属性的时候通常须要向以下的格局进行书写 student.profile.school.name,然而如果studentprofile属性不存在,那么就会抛出以下谬误:

Uncaught TypeError: Cannot read property 'school' of undefined

所以为了防止这种状况,咱们能够通过 if 条件语句判断一下 studentprofile属性是否存在,如果存在才会持续拜访外部的属性

if (student.profile && student.profile.school) {return student.profile.school.name}

然而下面这种写法太长了,须要检测对象是否具备某个属性。这种状况就能够应用 ?. 语法来判断对象上是否有该属性,具体应用形式如下:

return student?.profile?.school.name

这就防止了在拜访对象属性的时候可能会呈现报错的状况

欢送关注「前端好好学」,前端学习不迷路或加微信 ssdwbobo,一起交流学习

退出移动版