关于前端:细数各版本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,一起交流学习

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理