乐趣区

关于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

退出移动版