ES7、ES8 更新點(diǎn)梳理

ES7 和 ES8 出來的時(shí)間已經(jīng)蠻長了,對(duì)于瀏覽器的支持也比較好,正巧昨天在調(diào)研如何優(yōu)化 web-worker 的時(shí)候看到了一個(gè)新特性,順便與大家分享一下,大佬勿噴

ES7

在 ES7 中,只新增了數(shù)組的 includes 和簡寫的位運(yùn)算符,我來給大家舉個(gè)例子吧

1.Array.prototype.includes(value, formIndex)

  • 該方法確定確定某一個(gè)值是否存在于當(dāng)前數(shù)組中
參數(shù)
  • value: 需要查找的值

  • formIndex: 從指定位置開始查找

返回值
  • 返回值是一個(gè) Boolean 值,true 代表包含,false 代表不包含
const arr = [1, 2, 3, NaN]

// 最簡單使用

console.log(arr.includes(2)) // 返回 true
console.log(arr.includes(5)) // 返回 false
console.log(arr.includes(NaN)) // 返回 true

// 當(dāng)我們知道查詢的值大概范圍時(shí) (吐槽一下:一直覺得這個(gè)參數(shù)雞肋的一批)

// formIndex > 數(shù)組長度
console.log(arr.includes(2,5)) // 返回 false

// formIndex < 0
console.log(arr.includes(2, -1)) // 返回 false
console.log(arr.includes(2, -3)) // 返回 true

注:這個(gè)地方有一個(gè)它內(nèi)置的計(jì)算公示: arr.length + formIndex <= arr.length 如果上述條件滿足,將從計(jì)算后的位置查詢當(dāng)前值,不滿足的話,會(huì)從整個(gè)數(shù)組中查詢

2.指數(shù)運(yùn)算簡寫 **

  • 原來我們?cè)谟?jì)算 2 的 10 次方時(shí),寫法一般都是這樣的
const num1 = Math.pow(2, 10)
  • 那其實(shí)我們現(xiàn)在可以這樣去寫
const num2 = 2 ** 10

// 驗(yàn)證一下是否相等
console.log(num1 === num2) // 返回 true
  • 這樣去寫的話,是不是又可以少寫幾個(gè)字母了~~

ES8

ES8 中我們現(xiàn)在用的最多的首當(dāng)其沖是 async/await 了,那其實(shí)還有很多有意思的東西,我們可以看看

1.async/await

我們分開介紹吧

  • async 這個(gè)關(guān)鍵字可以將一個(gè) function 聲明成為一個(gè)異步方法,返回值是一個(gè) Promise
async function getNumber(num) {
  return num + 10
}
// 同樣的方法可以寫成這樣
const getNumber = async (num) => {
    return num + 10
}
console.log(getNumber(10)) // 返回 Promise {<fulfilled>: 20}

  • 如果返回值是一個(gè) promise 的話,我們其實(shí)獲取值也可以這樣寫
getNumber(10).then(res => console.log(res))
  • await 這個(gè)關(guān)鍵字和 async 一起使用的時(shí)候就體現(xiàn)出了優(yōu)勢。該關(guān)鍵字只能在 異步函數(shù) 中才會(huì)起作用
function promiseFn() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("result");
    }, 1500);
  });
}
async function fn() {
  let res = await promiseFn();
  console.log("異步代碼執(zhí)行完畢", res);
}
fn(); // wait 1.5s 后,打印 異步代碼執(zhí)行完畢, result

注:多個(gè)異步方法需要同時(shí)執(zhí)行,可以使用 await Promise.all[promise1,promise2]

2.Object.values() 和 Object.entries()

  • Object.values() 方法返回一個(gè)給定對(duì)象自身所有的 key,其中是不包含繼承來的 key

  • Object.entries() 方法返回一個(gè)數(shù)組,包含當(dāng)前Object中自身所有鍵值對(duì),同樣不包含繼承來的值

const obj = { name: 'tal', age: 17 };

console.log(Object.values(obj)); //返回 ['tal', 17]

console.log(Object.entries(obj)); //返回  [['name', 'tal'],['age', 17]]

// 其實(shí)對(duì)于我們平常開發(fā)來說,還是提高了一些效率的
// 例如:遍歷對(duì)象的鍵值
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key}-${value}`);
});


// 如果傳入的是字符串會(huì)怎樣
Object.values('tal') //返回 ["t", "a", "l"]
Object.entries('tal') // 返回 [['0': 't'], ['1': 'a'], ['2': 'l']]

注: 在使用這兩個(gè)屬性時(shí),會(huì)發(fā)生一個(gè)隱式的類型轉(zhuǎn)化,將我們傳入的值轉(zhuǎn)為 Object 后,再執(zhí)行方法

3.String padding

String 新增了兩個(gè)實(shí)例函數(shù) String.prototype.padStartString.prototype.padEnd ,允許將空字符串或其他字符串添加到原始字符串的開頭或結(jié)尾。

參數(shù)
  • targetLength: 當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
  • padString: (可選)填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)啵藚?shù)的缺省值為 ' '。
// 簡單寫法
console.log('0.0'.padStart(4,'10')) //返回 10.0
console.log('0.0'.padEnd(4,'0')) //返回 0.00 
   
console.log('0.0'.padStart(20)) //返回 0.00    
console.log('0.0'.padEnd(10,'0')) //返回 0.00000000

4.結(jié)尾支持逗號(hào)

這個(gè)功能其實(shí)對(duì)于我們來說還是比較友好的

例如:一個(gè)方法或者對(duì)象,我們只是增加了一個(gè)屬性或者參數(shù),我們需要在最末尾先增加一個(gè)逗號(hào)后再添加新屬性或者參數(shù),這樣的話,在 git 上就會(huì)出現(xiàn)兩行改動(dòng),不是很友好

function fn(
    para1: number,
    para: number,
){
    console.log(para1,para);
}
fn(1,2);

let obj = {
    n:'',
    n:'',
}

在支持這樣的語法后,我們就可以改一下我們的格式化工具了,避免了提交中會(huì)多出的一些改動(dòng)

5.Object.getOwnPropertyDescriptors()

該函數(shù)函數(shù)用來獲取一個(gè)對(duì)象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對(duì)象。

const obj = {
  name: "tal",
  get fn() {
    return "fn";
  }
};

const obj1 = {}
console.log(Object.getOwnPropertyDescriptors(obj1))
console.log(Object.getOwnPropertyDescriptors(obj))
  1. SharedArrayBuffer 與 Atomics

整個(gè)梳理了一遍 ES7 和 ES8 的東西后,終于開始聊重頭戲了,在用 web-worker 的老師們,可以看看這個(gè)東西是不是正好滿足了你當(dāng)前的需求

是不是還在為 worker 線程不能直接獲取到主線程的變量而苦惱
是不是還在頻繁的使用 postMessage 而感到繁瑣
嘗試一下 SharedArrayBuffer 吧(好像一段廣告詞...)

直接上代碼

// 這里是主進(jìn)程代碼
// 創(chuàng)建一個(gè)worker進(jìn)程
const worker = new Worker("./worker.js");

// 新建1kb內(nèi)存
const sharedBuffer = new SharedArrayBuffer(1024);

//  建視圖
const intArrBuffer = new Int32Array(sharedBuffer);

for (let i = 0; i < intArrBuffer.length; i++) {
  intArrBuffer[i] = i;
}
// console.log(sharedBuffer);
// postMessage  發(fā)送的共享內(nèi)存地址
worker.postMessage(intArrBuffer);

worker.onmessage = function(e) {
  console.log("更改后的數(shù)據(jù)", Atomics.load(intArrBuffer, 20)); // 返回 99
};
// 這里是 worker 的代碼
onmessage = function(e) {
  let arrBuffer = e.data; // 這里就可以獲取到
  console.log(Atomics.load(arrBuffer, 20))
  // 我們改一下它
  Atomics.store(arrBuffer, 20, 99); // 返回 99
};

這段代碼實(shí)際就是在內(nèi)存中創(chuàng)建了一個(gè) 1kb 的內(nèi)存,然后我將其中的內(nèi)容循環(huán)改成數(shù)字后,發(fā)送給子進(jìn)程(還是需要 PostMessage )的,但是內(nèi)存中的讀寫速度要比使用 PostMessage 快了很多,感興趣的老師可以試試

SharedArrayBuffer 是 js 開啟多線程的第一步,一提到多線程,我們一定會(huì)想到競爭,同樣的去修改同一個(gè)變量下的同一個(gè)元素怎么辦?答:多個(gè)共享內(nèi)存的線程能夠同時(shí)讀寫同一位置上的數(shù)據(jù)。原子操作會(huì)確保正在讀或?qū)懙臄?shù)據(jù)的值是符合預(yù)期的,即下一個(gè)原子操作一定會(huì)在上一個(gè)原子操作結(jié)束后才會(huì)開始,其操作過程不會(huì)中斷。

這個(gè)時(shí)候就出現(xiàn)了 Atomics, 它對(duì)象提供了一組靜態(tài)方法用來對(duì) SharedArrayBuffer 對(duì)象進(jìn)行原子操作。這些原子操作屬于 Atomics 模塊。與一般的全局對(duì)象不同,Atomics 不是構(gòu)造函數(shù),因此不能使用 new 操作符調(diào)用,也不能將其當(dāng)作函數(shù)直接調(diào)用。Atomics 的所有屬性和方法都是靜態(tài)的。

我們來看看它有什么方法:

  • Atomics.add() 將指定位置上的數(shù)組元素與給定的值相加,并返回相加前的值
  • Atomics.and() 將指定位置上的數(shù)組元素與給定的值相與,返回操作前的值
  • Atomics.load() 返回?cái)?shù)組中指定位置的值
  • Atomics.store() 改動(dòng)其中的某個(gè)值,并返回改動(dòng)后的值
  • Atomics.wait() 如果當(dāng)前的值等于給定的值,線程會(huì)被阻塞等待
  • Atomics.notify() 將當(dāng)前等待的進(jìn)程喚醒
    ...

它提供的方法還是很多的,剩下的留給大佬們自己實(shí)踐一下(測試的時(shí)候需要啟動(dòng)服務(wù)哈,worke需要)...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容