关于javascript:ES-的新特性

一、es7 新个性

1、Array.prototype.includes() 办法

该办法能够返回一个布尔值,示意某个数组是否蕴含给定的值,与字符串的includes办法相似。

[1,2,3].includes(4) // false
['ss', 'aa'].includes('aa') // true

该办法承受2个参数,第二个参数示意搜寻的起始地位,默认为0。如果参数为正数,则示意倒数。

[1, 2, 3].includes(3, 3) // true
[1, 2, 3].includes(3, -1) // true 

咱们通常应用indexOf来查看是否蕴含某个元素,然而会有毛病:一是不够直观,要和-1去比拟;二是它外部应用严格相等(===)来判断,导致会对NaN的误判。

[NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true
浏览器反对状况

目前只有IE不反对。

2、求幂运算符**

**具备与Math.pow()同样的计算成果。

console.log(2**10) // 1024
console.log(Math.pow(2, 10)) // 1024
浏览器反对状况

目前只有IE浏览器不反对。

二、es8 新个性

1、async/await异步解决方案

提出场景:JS 是单线程、优化回调天堂的写法。

es6为了解决回调的形式,提出了promisethen函数,然而当业务逻辑过多时,须要多个then函数,此时语义上不是很清晰。

new Promise( (resolve, reject) =>  {
  this.login(resolve)
}).then(() => this.getInfo())
  .then(() => {// do something})
  .catch(() => { console.log("Error") })

基于上述,引入了async/await,提供了在不阻塞主线程的状况下应用同步代码来实现异步拜访资源的能力,其中await不能够脱离async独自应用,且await前面肯定是Promise对象,如果不是会主动包装成Promise对象。

async function getInfo() {
  const result1 = await this.login()
  const result2 = await this.getInfo()
}

async能够独自应用,且返回的是一个Promise对象,且其外部return语句的返回值,会成为then办法回调函数的参数。

async function f() {
  return 'hello world';
}

f().then(val => console.log(val)) // hello world

具体对于async的用法,可参考 es6.ruanyifeng.com/#docs/async

浏览器反对状况

2、Object.values()/Object.entries()办法

Object.values()办法会返回一个数组,其数组成员是参数对象本身可枚举属性的键值。

留神:当属性值是数值时,会依照数值大小从小到大遍历。

const obj1 = { foo: 'bar', baz: 42 }
Object.values(obj1) // ["bar", 42]

const obj2 = { 100: 'a', 1: 'b', 2: 'c' }
Object.values(obj2) // ["b", "c", "a"]

Object.entries()办法返回一个数组,数组成员是参数对象本身可枚举属性的键值对数组。

const obj1 = { foo: 'bar', baz: 42 }
Object.entries(obj1) // [ ["foo, "bar"], ["baz", 42] ]

const obj2 = { 100: 'a', 1: 'b', 2: 'c' }
Object.entries(obj2) // [ ["1", "b"], ["2", "c"], ["100", "a"] ]
浏览器反对状况

目前只有IE浏览器不反对。

3、字符串填充padStart()/padEnd()办法

用于字符串补全长度的性能呢,如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

padStart()/padEnd()办法接管2个参数,第一个参数是字符串补全失效的最大长度,第二个参数是用来补全的字符串。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padEnd(5, 'ab') // 'xabab'

'xxx'.padStart(2, 'ab') // 'xxx'

如果用来补全的字符串与原字符串,两者的长度之和超过了最大长度,则会截去超出位数的补全字符串。

'abc'.padStart(8, 'xxx') // 'xxxxxabc'
浏览器反对状况

目前只有IE浏览器不反对。

4、Object.getOwnPropertyDescriptors()

提出场景:为了解决Object.assign()无奈正确拷贝get属性和set属性的问题。
Object.assign办法总是拷贝一个属性的值,而不会拷贝它背地的赋值办法或取值办法。

const source = {
  set foo(value) {
    console.log(value);
  }
};

const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo')

ES5 的Object.getOwnPropertyDescriptor()办法会返回某个对象属性的形容对象(descriptor),而Object.getOwnPropertyDescriptors()办法,返回指定对象所有本身属性(非继承属性)的形容对象。

浏览器反对状况

目前只有IE不反对

三、es9 新个性

1、Promise.prototype.finally()

finally()办法返回一个Promise, 在Promise执行完结时,无论后果是fulfilled或者是rejected,都会执行finally指定的回调函数。

let p = new Promise((resolve, reject) => {
    resolve()
})

p.then(() => 
    console.log(1) // 1
).catch((err) => {
    console.log(err)
}).finally(() => {
    console.log('finally') // 'finally'
})
浏览器反对状况

目前只有IE 不反对。

2、对象扩大运算符...

与数组相似,引入了对象扩大运算符,能够将一个对象的属性拷贝到另一个对象上,实现的是浅拷贝。

let form = {
    age: 11,
    name: 'John'
}

let params = {
    ...form,
    profession: 'student'
}
3、for await ... of

for ... of 循环用来遍历同步的迭代器接口,而for await ... of是异步迭代器,会期待前一个成员的状态扭转后才会遍历到下一个成员,相当于async函数外部的await

function getTime (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time)
    }, time)
  })
}
async function test () {
  let arr = [getTime(2000), getTime(100), getTime(3000)]
  for await (let item of arr) {
    console.log(Date.now(), item)
  }
}
test()
// 1598251267580 2000
// 1598251267580 100
// 1598251268583 3000
浏览器反对状况

Edge 不反对。

四、es10 新个性

1、Array.prototype.flat()

Array.prototype.flat()用于将嵌套的数组“拉平”,变成一维的数组。该办法返回一个新数组,对原数据没有影响。

flat()办法默认会“拉平”一层,能够传入整数作为参数,示意想要拉平的层数,默认是1。

[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]

[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]

当对嵌套多层的数组想要转成一维数组,能够传入关键字Infinity

[1, [2, [3]]].flat(Infinity) // [1, 2, 3]

如果原数组有空位,flat()会跳过空位。

[1, , 2, , 3, 4].flat() // [1, 2, 3, 4]
浏览器反对状况

目前只有IE 和 Edge不反对。

2、Array.prototype.flatMap()

flatMap()办法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),而后对返回值组成的数组执行flat()办法。该办法返回一个新数组,不扭转原数组。

let arr = [1, 2, 3]
console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]
console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]

实际上flatMap是综合了mapflat的操作,所以它也只能打平一层

[1, 2, 3, 4].flatMap(x => [x * 2]) // [2, 4, 6, 8]

[1, 2, 3, 4].flatMap(x => [[x * 2]]) // [[2], [4], [6], [8]]
浏览器反对状况

目前只有IE 和 Edge不反对。

3、Object.fromEntries()

Object.fromEntries()办法是Object.entries()的逆操作,用于将一个键值对数组转为对象。

const entries = new Map([
    ['age', 10],
    ['name', 'Amy']
])

Object.fromEntries(entries) // { age: 10, name: 'Amy' }
浏览器反对状况

目前只有IE、Edge、Opera for Android、Samsung Internet不反对。

4、String.trimStart()/String.timeEnd()

这两个办法的行为与trim()统一,trimStart()打消字符串头部的空格,trimEnd()打消字符串尾部的空格,且不会扭转原始字符串。

const str = '   lalallal  '
str.trim()       // 'lalallal'
str.trimStart()  // 'lalallal  '
str.trimEnd()    // '   lalallal'
浏览器反对状况

目前只有IE不反对。

5、try...catch

catch中的参数变成一个可选项。

try {
 console.log(1)
} catch {
 console.log(2)
}
浏览器反对状况

6、Function.prototype.toString()

批改后的toString()办法,会返回和原函数截然不同的原始代码。

function /* foo comment */ foo () {}

foo.toString() // "function /* foo comment */ foo () {}"
浏览器反对状况

7、Symbol.prototype.description

咱们在创立Symbol时,能够增加一个形容。

读取时要显示转为字符串通过toString()办法才能够读取。

const sym = Symbol('foo');

String(sym) // "Symbol(foo)"
sym.toString() // "Symbol(foo)"

description属性,能够间接不便的返回Symbol的形容。

const sym = Symbol('foo');

sym.description // "foo"
浏览器反对状况

只有Edge、IE 不反对。

五、es11 新个性

一、ES2020

1、可选链操作符?.
let title = data && data.result && data.result.title

// 之后
let title = data?.result?.title

如果data 或者 data.result是null/undefined,表达式将会短路计算间接返回undefined。

浏览器反对状况

目前只有Chrome 79 及 Opera 65及以上版本反对。

2、空位合并操作符 ??
// 之前
'' || 'default value' // 'default value'
0 || 'default value' // 'default value'

// 之后
'' || 'default value' // ''

??左侧只有是undefinednull时,才返回右侧默认值,否则都为左侧的值。

let c = a ?? b
// 等价于
let c = a !== undefined && a !== null ? a : b
浏览器反对状况

目前只有Chrome 80 及 Firefox 72及以上版本反对。

3、BigInt 任意精度整数

js 只能平安的标识-(2^53-1)至 2^53-1范畴的值,超出这个范畴的整数计算会失落精度。

var num = Number.MAX_SAFE_INTEGER // 9007199254740991

var num1 = num + 1 // 9007199254740992
var num2 = num + 2 // 9007199254740992


9007199254740992 === 9007199254740993 // true

于是产生了BigInt它是第七个原始类型,能够进行大数整数运算,应用时须要再数字前面加上n,或者应用BigInt()办法进行转化。

var a = 111
var big = BigInt(a)

big === 111n //true
typeof big === 'bigint' // true
typeof 111n // bigint

1222223456789098765n +2n // 1222223456789098767n
浏览器反对状况

目前只有Chrome 67 及 Firefox 68及以上版本反对。

4、import() 动静加载

返回一个Promise 对象,且当加载模块胜利当前,这个模块会作为一个对象,当作then办法的参数。

const modulePage = 'page.js'; 

import(modulePage)
     .then((module) => {
        module.default();
     });

这种形式也反对 await关键字。

(async () => {
  const helpersModule = 'helpers.js';
  const module = await import(helpersModule)
  const total = module.sum(2, 2);
})();
浏览器反对状况

目前除了IE和edge不反对,Chrome 是63及以上版本反对。

5、globalThis

用于获取全局this
在浏览器中国是window,在 web workers中是self,在node中是global

// 之前
const 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')
}

globalThis目标就是提供一标准化拜访全局对象,而不须要思考不同的环境问题。

// worker.js
globalThis === self

// node.js
globalThis === global

// browser.js
globalThis === window
浏览器反对状况

目前除了IE、Opera和edge不反对,Chrome 是71及以上版本反对。

6、Promise.allSettled

Promise.all具备并发执行异步工作的能力,然而最大问题是如果参数中有一个为reject,则整个Promise.all会立刻终止,并返回一个reject的新的Promise对象。


const promises = [
 Promise.resolve(1),
 Promise.resolve(2),
 Promise.reject('error')
];
 
 
Promise.all(promises)
 .then(responses => console.log(responses))

通常咱们可能会用 Promsie.all 来并发申请三个接口,如果一个接口reject了,则会导致三个接口数据全都无奈展现,而Promise.allSettled的呈现就能够解决这个痛点。

Promise.allSettled承受一个Promise 的数组,并返回一个新的数组,与Promise.all不同的是,它不会进行短路,而是能够拿到每一个Promise的状态。


Promise.allSettled([
  Promise.reject({ code: 500, msg: '服务异样' }),
  Promise.resolve({ code: 200, list: [] }),
  Promise.resolve({ code: 200, list: [] })
]).then(res => {
  console.log(res)
  /*
        0: {status: "rejected", reason: {…}}
        1: {status: "fulfilled", value: {…}}
        2: {status: "fulfilled", value: {…}}
    */
  // 过滤掉 rejected 状态,尽可能多的保障页面区域数据渲染
    res.filter(el => {
      return el.status !== 'rejected'
    })
})
浏览器反对状况

目前除了IE、Opera和edge不反对,Chrome 是76及以上版本反对。

7、String.prototype.matchAll

String.prototypematch()办法仅返回残缺的匹配后果,而不会返回正则表达式组的信息。

matchAll办法返回比match更多的信息,会蕴含全副的正则模式捕捉后果,而无需用修饰符/g

// match办法
const text = "From 2019.01.29 to 2019.01.30";
const regexp = /(?<year>\d{4}).(?<month>\d{2}).(?<day>\d{2})/gu;
const results = text.match(regexp);
console.log(results);
// [ '2019.01.29', '2019.01.30' ]
// matchAll 办法
const text = "From 2019.01.29 to 2019.01.30";
const regexp = /(?<year>\d{4}).(?<month>\d{2}).(?<day>\d{2})/gu;
const results = Array.from(text.matchAll(regexp));
console.log(results);
// [
//   [
//     '2019.01.29',
//     '2019',
//     '01',
//     '29',
//     index: 5,
//     input: 'From 2019.01.29 to 2019.01.30',
//     groups: [Object: null prototype] { year: '2019', month: '01', day: '29' }
//   ],
//   [
//     '2019.01.30',
//     '2019',
//     '01',
//     '30',
//     index: 19,
//     input: 'From 2019.01.29 to 2019.01.30',
//     groups: [Object: null prototype] { year: '2019', month: '01', day: '30' }
//   ]
// ]
浏览器反对状况

IE、Safari、Edge不反对。

TC39 Proposals

评论

发表回复

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

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