by rajaraodv
通過rajaraodv
以下是ECMAScript 2016、2017和2018中所有新增功能的示例 (Here are examples of everything new in ECMAScript 2016, 2017, and 2018)
It’s hard to keep track of what’s new in JavaScript (ECMAScript). And it’s even harder to find useful code examples.
很難跟蹤JavaScript(ECMAScript)的新功能。 而且,找到有用的代碼示例更加困難。
So in this article, I’ll cover all 18 features that are listed in the TC39’s finished proposals that were added in ES2016, ES2017, and ES2018 (final draft) and show them with useful examples.
因此,在本文中,我將介紹TC39最終提案中列出的全部18個功能,這些提案已添加到ES2016,ES2017和ES2018(最終草案)中,并通過有用的示例進行展示。
This is a pretty long post but should be an easy read. Think of this as “Netflix binge reading.” By the end of this, I promise that you’ll have a ton of knowledge about all these features.
這是一篇相當長的文章,但應該很容易閱讀。 將此視為“ Netflix暴飲暴食”。 到此為止,我保證您將對所有這些功能有很多了解。
好,讓我們一一介紹。 (OK, let’s go over these one by one.)
1. Array.prototype.includes
(1. Array.prototype.includes
)
includes
is a simple instance method on the Array and helps to easily find if an item is in the Array (including NaN
unlike indexOf
).
includes
是Array上的一個簡單實例方法,可幫助輕松查找是否在Array中(包括與indexOf
不同的NaN
)。
Trivia: the JavaScript spec people wanted to name it
contains
, but this was apparently already used by Mootools so they usedincludes
.Trivia:人們希望將JavaScript規范命名為
contains
,但Mootools顯然已經使用了它,因此他們使用了includes
。
2.
求冪中infix operator
(2.
Exponentiation infix operator
)
Math operations like addition and subtraction have infix operators like +
and -
, respectively. Similar to them, the **
infix operator is commonly used for exponent operation. In ECMAScript 2016, the **
was introduced instead of Math.pow
.
數學運算(例如加法和減法)分別具有中綴運算符(例如+
和-
)。 與它們相似, **
infix運算符通常用于指數運算。 在ECMAScript 2016中,引入了**
而不是Math.pow
。
1. Object.values() (1. Object.values())
Object.values()
is a new function that’s similar to Object.keys()
but returns all the values of the Object’s own properties excluding any value(s) in the prototypical chain.
Object.values()
是一個類似于Object.keys()
的新函數,但返回對象自身屬性的所有值,但不包括原型鏈中的任何值。
2. Object.entries() (2. Object.entries())
Object.entries()
is related to Object.keys
, but instead of returning just keys, it returns both keys and values in the array fashion. This makes it very simple to do things like using objects in loops or converting objects into Maps.
Object.entries()
與Object.keys
有關,但它不僅返回鍵,還以數組形式返回鍵和值。 這樣就很容易執行諸如在循環中使用對象或將對象轉換為Map之類的事情。
Example 1:
范例1:
Example 2:
范例2:
3.字符串填充 (3. String padding)
Two instance methods were added to String — String.prototype.padStart
and String.prototype.padEnd
— that allow appending/prepending either an empty string or some other string to the start or the end of the original string.
在String中添加了兩個實例方法String.prototype.padStart
和String.prototype.padEnd
允許將空字符串或其他字符串附加/添加到原始字符串的開頭或結尾。
'someString'.padStart(numberOfCharcters [,stringForPadding]); '5'.padStart(10) // ' 5'
'5'.padStart(10, '=*') //'=*=*=*=*=5''5'.padEnd(10) // '5 '
'5'.padEnd(10, '=*') //'5=*=*=*=*='
This comes in handy when we want to align things in scenarios like pretty print display or terminal print.
當我們想要在漂亮的打印顯示器或終端打印等場景中對齊內容時,這非常方便。
3.1 padStart示例: (3.1 padStart example:)
In the below example, we have a list of numbers of varying lengths. We want to prepend “0” so that all the items have the same length of 10 digits for display purposes. We can use padStart(10, '0')
to easily achieve this.
在下面的示例中,我們列出了不同長度的數字。 我們想在前面加上“ 0”,以便所有項目都具有相同的10位數字長度以用于顯示。 我們可以使用padStart(10, '0')
輕松實現這一目標。
3.2 padEnd示例: (3.2 padEnd example:)
padEnd
really comes in handy when we are printing multiple items of varying lengths and want to right-align them properly.
當我們要打印長度不同的多個項目并希望正確對齊它們時, padEnd
確實派上了用場。
The example below is a good realistic example of how padEnd
, padStart
, and Object.entries
all come together to produce a beautiful output.
下面的示例是一個很好的現實示例,說明padEnd
, padStart
和Object.entries
如何共同產生漂亮的輸出。
const cars = {'🚙BMW': '10','🚘Tesla': '5','🚖Lamborghini': '0'
}Object.entries(cars).map(([name, count]) => {//padEnd appends ' -' until the name becomes 20 characters//padStart prepends '0' until the count becomes 3 characters.console.log(`${name.padEnd(20, ' -')} Count: ${count.padStart(3, '0')}`)
});//Prints..
// 🚙BMW - - - - - - - Count: 010
// 🚘Tesla - - - - - - Count: 005
// 🚖Lamborghini - - - Count: 000
3.3表情符號和其他雙字節字符上的??padStart和padEnd (3.3 ?? padStart and padEnd on Emojis and other double-byte chars)
Emojis and other double-byte chars are represented using multiple bytes of unicode. So padStart and padEnd might not work as expected!??
表情符號和其他雙字節字符使用多個字節的unicode表示。 所以padStart和padEnd可能無法按預期工作!??
For example: Let’s say we are trying to pad the string heart
to reach 10
characters with the ?? emoji. The result will look like below:
例如:假設我們正嘗試使用??表情符號填充字符串的heart
以使其達到10
字符。 結果將如下所示:
//Notice that instead of 5 hearts, there are only 2 hearts and 1 heart that looks odd!
'heart'.padStart(10, "??"); // prints.. '?????heart'
This is because ?? is 2 code points long ('\u2764\uFE0F'
)! The word heart
itself is 5 characters, so we only have a total of 5 chars left to pad. So what happens is that JS pads two hearts using '\u2764\uFE0F'
and that produces ????. For the last one it simply uses the first byte of the heart \u2764
which produces ?
這是因為??的長度為2個代碼點( '\u2764\uFE0F'
)! “ heart
”一詞本身是5個字符,因此我們只剩下5個字符。 因此,發生的事是JS使用'\u2764\uFE0F'
并且產生了????。 對于最后一個,它僅使用心臟\u2764
的第一個字節產生?
So we end up with: ?????heart
所以我們最終得到了: ?????heart
PS: You may use this link to check out unicode char conversions.
PS:您可以使用此鏈接簽出Unicode字符轉換。
4. Object.getOwnPropertyDescriptors
(4. Object.getOwnPropertyDescriptors
)
This method returns all the details (including getter get
and setter set
methods) for all the properties of a given object. The main motivation to add this is to allow shallow copying / cloning an object into another object that also copies getter and setter functions as opposed to Object.assign
.
此方法返回給定對象的所有屬性的所有詳細信息(包括getter get
和setter set
方法)。 添加它的主要動機是允許將對象淺復制/克隆到另一個對象中 這也復制了getter和setter函數,而不是Object.assign
。
Object.assign shallow copies all the details except getter and setter functions of the original source object.
Object.assign淺表會復制除原始源對象的getter和setter函數之外的所有詳細信息。
The example below shows the difference between Object.assign
and Object.getOwnPropertyDescriptors
along with Object.defineProperties
to copy an original object Car
into a new object ElectricCar
. You’ll see that by using Object.getOwnPropertyDescriptors
,discount
getter and setter functions are also copied into the target object.
下面的示例顯示了Object.assign
和Object.getOwnPropertyDescriptors
以及Object.defineProperties
之間的區別,該區別將原始對象Car
復制到新對象ElectricCar
。 您將看到使用Object.getOwnPropertyDescriptors
, discount
getter和setter函數也被復制到目標對象中。
BEFORE…
之前…
AFTER…
后…
var Car = {name: 'BMW',price: 1000000,set discount(x) {this.d = x;},get discount() {return this.d;},
};//Print details of Car object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(Car, 'discount'));
//prints..
// {
// get: [Function: get],
// set: [Function: set],
// enumerable: true,
// configurable: true
// }//Copy Car's properties to ElectricCar using Object.assign
const ElectricCar = Object.assign({}, Car);//Print details of ElectricCar object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(ElectricCar, 'discount'));
//prints..
// {
// value: undefined,
// writable: true,
// enumerable: true,
// configurable: true
// }
//??Notice that getters and setters are missing in ElectricCar object for 'discount' property !👎👎//Copy Car's properties to ElectricCar2 using Object.defineProperties
//and extract Car's properties using Object.getOwnPropertyDescriptors
const ElectricCar2 = Object.defineProperties({}, Object.getOwnPropertyDescriptors(Car));//Print details of ElectricCar2 object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(ElectricCar2, 'discount'));
//prints..
// { get: [Function: get], 👈🏼👈🏼👈🏼
// set: [Function: set], 👈🏼👈🏼👈🏼
// enumerable: true,
// configurable: true
// }
// Notice that getters and setters are present in the ElectricCar2 object for 'discount' property!
5. Add trailing commas in the function parameters
(5. Add trailing commas in the function parameters
)
This is a minor update that allows us to have trailing commas after the last function parameter. Why? To help with tools like git blame to ensure only new developers get blamed.
這是一個較小的更新,它使我們可以在最后一個函數參數之后使用逗號結尾。 為什么? 幫助諸如git blame之類的工具,以確保只有新開發人員受到指責。
The below example shows the problem and the solution.
以下示例顯示了問題和解決方案。
Note: You can also call functions with trailing commas!
注意:您也可以使用尾隨逗號來調用函數!
6.異步/等待 (6. Async/Await)
This, by far, is the most important and most useful feature if you ask me. Async functions allows us to not deal with callback hell and make the entire code look simple.
如果您問我,這是迄今為止最重要和最有用的功能。 異步函數使我們不必處理回調地獄,并使整個代碼看起來很簡單。
The async
keyword tells the JavaScript compiler to treat the function differently. The compiler pauses whenever it reaches the await
keyword within that function. It assumes that the expression after await
returns a promise and waits until the promise is resolved or rejected before moving further.
async
關鍵字告訴JavaScript編譯器以不同的方式對待函數。 只要編譯器在該函數中到達await
關鍵字,它就會暫停。 它假定await
之后的表達式返回一個promise,并等待直到promise被解決或被拒絕后再繼續移動。
In the example below, the getAmount
function is calling two asynchronous functions getUser
and getBankBalance
. We can do this in promise, but using async await
is more elegant and simple.
在下面的示例中, getAmount
函數正在調用兩個異步函數getUser
和getBankBalance
。 我們可以按承諾來做到這一點,但是使用async await
更加優雅和簡單。
6.1異步函數本身返回一個Promise。 (6.1 Async functions themselves return a Promise.)
If you are waiting for the result from an async function, you need to use Promise’s then
syntax to capture its result.
如果您正在等待異步函數的結果,則需要使用Promise的then
語法來捕獲其結果。
In the following example, we want to log the result using console.log
but not within the doubleAndAdd. So we want to wait and use then
syntax to pass the result to console.log
.
在下面的示例中,我們想使用console.log
記錄結果,而不是在doubleAndAdd中記錄結果。 所以我們要等待, then
使用語法將結果傳遞給console.log
。
6.2并行調用異步/等待 (6.2 Calling async/await in parallel)
In the previous example we are calling await twice, but each time we are waiting for one second (total 2 seconds). Instead we can parallelize it since a
and b
are not dependent on each other using Promise.all
.
在前面的示例中,我們兩次調用await,但是每次等待一秒鐘(總計2秒)。 相反,我們可以并行化它,因為使用Promise.all
可以使a
和b
彼此不依賴。
6.3錯誤處理異步/等待功能 (6.3 Error handling async/await functions)
There are various ways to handle errors when using async await.
使用異步等待時,有多種處理錯誤的方法。
選項1-在函數中使用try catch (Option 1 — Use try catch within the function)
//Option 1 - Use try catch within the function
async function doubleAndAdd(a, b) {try {a = await doubleAfter1Sec(a);b = await doubleAfter1Sec(b);} catch (e) {return NaN; //return something}
return a + b;
}//🚀Usage:
doubleAndAdd('one', 2).then(console.log); // NaN
doubleAndAdd(1, 2).then(console.log); // 6function doubleAfter1Sec(param) {return new Promise((resolve, reject) => {setTimeout(function() {let val = param * 2;isNaN(val) ? reject(NaN) : resolve(val);}, 1000);});
}
選項2-捕獲每個等待的表達式 (Option 2— Catch every await expression)
Since every await
expression returns a Promise, you can catch errors on each line as shown below.
由于每個await
表達式都返回一個Promise,因此您可以在每一行中捕獲錯誤,如下所示。
//Option 2 - *Catch* errors on every await line
//as each await expression is a Promise in itself
async function doubleAndAdd(a, b) {a = await doubleAfter1Sec(a).catch(e => console.log('"a" is NaN')); // 👈b = await doubleAfter1Sec(b).catch(e => console.log('"b" is NaN')); // 👈if (!a || !b) {return NaN;}return a + b;
}//🚀Usage:
doubleAndAdd('one', 2).then(console.log); // NaN and logs: "a" is NaN
doubleAndAdd(1, 2).then(console.log); // 6function doubleAfter1Sec(param) {return new Promise((resolve, reject) => {setTimeout(function() {let val = param * 2;isNaN(val) ? reject(NaN) : resolve(val);}, 1000);});
}
選項3-捕獲整個異步等待功能 (Option 3 — Catch the entire async-await function)
//Option 3 - Dont do anything but handle outside the function
//since async / await returns a promise, we can catch the whole function's error
async function doubleAndAdd(a, b) {a = await doubleAfter1Sec(a);b = await doubleAfter1Sec(b);return a + b;
}//🚀Usage:
doubleAndAdd('one', 2)
.then(console.log)
.catch(console.log); // 👈👈🏼<------- use "catch"function doubleAfter1Sec(param) {return new Promise((resolve, reject) => {setTimeout(function() {let val = param * 2;isNaN(val) ? reject(NaN) : resolve(val);}, 1000);});
}
ECMAScript is currently in final draft and will be out in June or July 2018. All the features covered below are in Stage-4 and will be part of ECMAScript 2018.
ECMAScript目前處于最終草案中,將于2018年6月或7月發布。下面介紹的所有功能均在Stage-4中,并將成為ECMAScript 2018的一部分。
1. 共享內存和原子 (1. Shared memory and atomics)
This is a huge, pretty advanced feature and is a core enhancement to JS engines.
這是一個巨大的高級功能,是JS引擎的核心增強功能。
The main idea is to bring some sort of multi-threading feature to JavaScript so that JS developers can write high-performance, concurrent programs in the future by allowing to manage memory by themselves instead of letting JS engine manage memory.
主要思想是為JavaScript帶來某種多線程功能,以便JS開發人員將來可以通過允許自己管理內存而不是讓JS引擎管理內存來編寫高性能的并發程序。
This is done by a new type of a global object called SharedArrayBuffer that essentially stores data in a shared memory space. So this data can be shared between the main JS thread and web-worker threads.
這是通過一種稱為SharedArrayBuffer的新型全局對象完成的,該對象實際上將數據存儲在共享 內存空間中 。 因此,可以在JS主線程和Web工作者線程之間共享此數據。
Until now, if we want to share data between the main JS thread and web-workers, we had to copy the data and send it to the other thread using postMessage
. Not anymore!
到目前為止,如果要在JS主線程和Web工作者之間共享數據,則必須復制數據并使用postMessage
將其發送到另一個線程。 不再!
You simply use SharedArrayBuffer and the data is instantly accessible by both the main thread and multiple web-worker threads.
您只需使用SharedArrayBuffer,主線程和多個Web工作者線程都可以立即訪問數據。
But sharing memory between threads can cause race conditions. To help avoid race conditions, the “Atomics” global object is introduced. Atomics provides various methods to lock the shared memory when a thread is using its data. It also provides methods to update such data in that shared memory safely.
但是在線程之間共享內存可能會導致爭用情況。 為了避免出現競爭情況,引入了“ Atomics ”全局對象。 原子提供了多種方法來在線程使用其數據時鎖定共享內存。 它還提供了安全地更新該共享內存中此類數據的方法。
The recommendation is to use this feature via some library, but right now there are no libraries built on top of this feature.
建議通過一些庫使用此功能,但是目前在此功能之上沒有庫。
If you are interested, I recommend reading:
如果您有興趣,我建議閱讀:
From Workers to Shared Memory — lucasfcosta
從工人到共享記憶 -lucasfcosta
A cartoon intro to SharedArrayBuffers — Lin Clark
SharedArrayBuffers的卡通簡介 — Lin Clark
Shared memory and atomics — Dr. Axel Rauschmayer
共享內存和原子 — Axel Rauschmayer博士
2.刪除了標記模板字面量限制 (2. Tagged Template literal restriction removed)
First, we need to clarify what a “Tagged Template literal” is so we can understand this feature better.
首先,我們需要弄清楚“標記模板文字”是什么,以便我們可以更好地理解此功能。
In ES2015+, there is a feature called a tagged template literal that allows developers to customize how strings are interpolated. For example, in the standard way strings are interpolated like below…
在ES2015 +中,有一個稱為標記模板文字的功能,該功能允許開發人員自定義字符串的內插方式。 例如,以標準方式插入字符串,如下所示……
In the tagged literal, you can write a function to receive the hardcoded parts of the string literal, for example [ ‘Hello ‘, ‘!’ ]
, and the replacement variables, for example,[ 'Raja']
, as parameters into a custom function (for example greet
), and return whatever you want from that custom function.
在帶標記的文字中,您可以編寫一個函數來接收字符串文字的硬編碼部分,例如[ 'Hello ', '!' ]
[ 'Hello ', '!' ]
和替換變量(例如[ 'Raja']
)作為自定義函數的參數(例如greet
),然后從該自定義函數返回所需的內容。
The below example shows that our custom “Tag” function greet
appends time of the day like “Good Morning!” “Good afternoon,” and so on depending on the time of the day to the string literal and returns a custom string.
下面的示例顯示了我們自定義的“標記”功能greet
像“早安!”那樣添加一天中的時間。 “下午好”,依此類推,取決于一天中的時間,返回字符串文字并返回自定義字符串。
//A "Tag" function returns a custom string literal.
//In this example, greet calls timeGreet() to append Good //Morning/Afternoon/Evening depending on the time of the day.function greet(hardCodedPartsArray, ...replacementPartsArray) {console.log(hardCodedPartsArray); //[ 'Hello ', '!' ]console.log(replacementPartsArray); //[ 'Raja' ]let str = '';hardCodedPartsArray.forEach((string, i) => {if (i < replacementPartsArray.length) {str += `${string} ${replacementPartsArray[i] || ''}`;} else {str += `${string} ${timeGreet()}`; //<-- append Good morning/afternoon/evening here}});return str;
}//🚀Usage:
const firstName = 'Raja';
const greetings = greet`Hello ${firstName}!`; //👈🏼<-- Tagged literalconsole.log(greetings); //'Hello Raja! Good Morning!' 🔥function timeGreet() {const hr = new Date().getHours();return hr < 12? 'Good Morning!': hr < 18 ? 'Good Afternoon!' : 'Good Evening!';
}
Now that we discussed what “Tagged” functions are, many people want to use this feature in different domains, like in Terminal for commands and HTTP requests for composing URIs, and so on.
現在,我們討論了什么是“標記”功能,許多人希望在不同的域中使用此功能,例如在Terminal中用于命令和用于編寫URI的HTTP請求,等等。
??標簽字符串文字的問題 (??The problem with Tagged String literal)
The problem is that ES2015 and ES2016 specs doesn’t allow using escape characters like “\u” (unicode), “\x”(hexadecimal) unless they look exactly like `\u00A9` or \u{2F804} or \xA9.
問題在于,ES2015和ES2016規范不允許使用轉義字符,例如“ \ u”(unicode),“ \ x”(十六進制),除非它們看起來與“ \ u00A9”或\ u {2F804}或\ xA9完全一樣。
So if you have a Tagged function that internally uses some other domain’s rules (like Terminal’s rules), that may need to use \ubla123abla that doesn’t look like \u0049 or \u{@F804}, then you would get a syntax error.
所以,如果你有一個標記功能在內部使用一些其他領域的規則(如終端的規則),可能需要使用\ ubla123abla并不像\ u0049或\∪{@ F804},然后你會得到一個語法錯誤。
In ES2018, the rules are relaxed to allow such seemingly invalid escape characters as long as the Tagged function returns the values in an object with a “cooked” property (where invalid characters are “undefined”), and then a “raw” property (with whatever you want).
在ES2018中,放寬了規則以允許使用看似無效的轉義字符,只要Tagged函數返回對象中具有``cooked''屬性(其中無效字符為``undefined'')和``raw''屬性(與您想要的任何東西)。
function myTagFunc(str) { return { "cooked": "undefined", "raw": str.raw[0] }
} var str = myTagFunc `hi \ubla123abla`; //call myTagFuncstr // { cooked: "undefined", raw: "hi \\unicode" }
3.正則表達式的“ dotall”標志 (3. “dotall” flag for Regular expression)
Currently in RegEx, although the dot(“.”) is supposed to match a single character, it doesn’t match new line characters like \n \r \f etc
.
當前在RegEx中,盡管點(“。”)應該匹配單個字符,但不匹配\n \r \f etc
換行符。
For example:
例如:
//Before
/first.second/.test('first\nsecond'); //false
This enhancement makes it possible for the dot operator to match any single character. In order to ensure this doesn’t break anything, we need to use \s
flag when we create the RegEx for this to work.
此增強功能使點運算符可以匹配任何單個字符。 為了確保它不會破壞任何內容,我們在創建RegEx時需要使用\s
標志來使其正常工作。
//ECMAScript 2018
/first.second/s.test('first\nsecond'); //true Notice: /s ??
Here is the overall API from the proposal doc:
這是提案文檔中的總體API:
4. RegExp命名組捕獲? (4. RegExp Named Group Captures ?)
This enhancement brings a useful RegExp feature from other languages like Python, Java and so on called “Named Groups.” This features allows developers writing RegExp to provide names (identifiers) in the format(?<name>...)
for different parts of the group in the RegExp. They can then use that name to grab whichever group they need with ease.
此增強功能帶來了其他語言(如Python,Java等)的有用的RegExp功能,稱為“命名組”。 此功能允許開發人員編寫RegExp,以便為RegExp中組的不同部分提供格式為(?<name>...)
名稱(標識符)。 然后,他們可以使用該名稱輕松地獲取所需的任何組。
4.1基本命名組示例 (4.1 Basic Named group example)
In the below example, we are using (?<year>) (?<month>) and (?<day>)
names to group different parts of the date RegEx. The resulting object will now contain a groups
property with properties year
, month
, and day
with corresponding values.
在下面的示例中,我們使用(?<year>) (?<month>) and (?<day>)
名稱對日期RegEx的不同部分進行分組。 現在,結果對象將包含一個groups
屬性,其屬性為year
, month
和day
,并具有相應的值。
4.2在正則表達式本身中使用命名組 (4.2 Using Named groups inside regex itself)
We can use the \k<group name>
format to back reference the group within the regex itself. The following example shows how it works.
我們可以使用\k<group name>
格式在正則表達式本身中向后引用該組。 以下示例顯示了它的工作方式。
4.3在String.prototype.replace中使用命名組 (4.3 Using named groups in String.prototype.replace)
The named group feature is now baked into String’s replace
instance method. So we can easily swap words in the string.
現在,已命名的組功能包含在String的replace
實例方法中。 因此,我們可以輕松地在字符串中交換單詞。
For example, change “firstName, lastName” to “lastName, firstName”.
例如,將“ firstName,lastName”更改為“ lastName,firstName”。
5.對象的其余屬性 (5. Rest properties for Objects)
Rest operator ...
(three dots) allows us to extract Object properties that are not already extracted.
Rest運算符...
(三個點)使我們能夠提取尚未提取的對象屬性。
5.1您可以使用rest幫助僅提取所需的屬性 (5.1 You can use rest to help extract only properties you want)
5.2甚至可以刪除不需要的物品! ?? (5.2 Even better, you can remove unwanted items! ??)
6.傳播對象的屬性 (6. Spread properties for Objects)
Spread properties also look just like rest properties with three dots ...
but the difference is that you use spread to create (restructure) new objects.
傳播屬性也看起來像帶有三個點的其余屬性...
但是區別在于您使用傳播來創建(重組)新對象。
Tip: the spread operator is used in the right side of the equals sign. The rest are used in the left-side of the equals sign.
提示:等號的右側使用了擴散算子。 其余的用于等號的左側。
7. RegExp后置斷言 (7. RegExp Lookbehind Assertions)
This is an enhancement to the RegEx that allows us to ensure some string exists immediately *before* some other string.
這是對RegEx的增強,它使我們能夠確保某些字符串在其他字符串之前*之前存在。
You can now use a group (?<=…)
(question mark, less than, equals) to look behind for positive assertion.
現在,您可以使用組(?<=…)
(問號,小于等于)來向后尋找肯定的斷言。
Further, you can use (?<!…)
(question mark, less than, exclamation), to look behind for a negative assertion. Essentially this will match as long as the -ve assertion passes.
此外,您可以使用(?<!…)
(問號,小于,感嘆號)來查找否定斷言。 本質上,只要-ve斷言通過,這將匹配。
Positive Assertion: Let’s say we want to ensure that the #
sign exists before the word winning
(that is: #winning
) and want the regex to return just the string “winning”. Here is how you’d write it.
正斷言:我們要確保我們說#
簽個字之前存在winning
:(即#winning
并希望正則表達式來僅返回字符串“中獎”)。 這是您的編寫方式。
Negative Assertion: Let’s say we want to extract numbers from lines that have € signs and not $ signs before those numbers.
否定斷言:假設我們要從在這些數字前帶有€符號而不是$符號的行中提取數字。
8. RegExp Unicode屬性轉義 (8. RegExp Unicode Property Escapes)
It was not easy to write RegEx to match various unicode characters. Things like \w
, \W
, \d
etc only match English characters and numbers. But what about numbers in other languages like Hindi, Greek, and so on?
編寫RegEx以匹配各種unicode字符并不容易。 \w
, \W
, \d
等僅匹配英文字符和數字。 但是其他語言(如印地語,希臘語等)中的數字呢?
That’s where Unicode Property Escapes come in. It turns out Unicode adds metadata properties for each symbol (character) and uses it to group or characterize various symbols.
這就是Unicode Property Escapes出現的地方。 事實證明Unicode為每個符號(字符)添加了元數據屬性,并使用它來對各種符號進行分組或表征。
For example, Unicode database groups all Hindi characters(??????) under a property called Script
with value Devanagari
and another property called Script_Extensions
with the same value Devanagari
. So we can search for Script=Devanagari
and get all Hindi characters.
例如,Unicode數據庫將所有印地語字符(??????)分組為一個名為Script
的屬性,其值為Devanagari
,另一個屬性名為Script_Extensions
,其屬性為Devanagari
。 因此,我們可以搜索Script=Devanagari
并獲取所有印地語字符。
Devanagari can be used for various Indian languages like Marathi, Hindi, Sanskrit, and so on.
梵文可以用于各種印度語言,例如馬拉地語,北印度語,梵語等。
Starting in ECMAScript 2018, we can use \p
to escape characters along with {Script=Devanagari}
to match all those Indian characters. That is, we can use: \p{Script=Devanagari}
in the RegEx to match all Devanagari characters.
從ECMAScript 2018開始,我們可以使用\p
轉義字符以及{Script=Devanagari}
以匹配所有這些印度字符。 也就是說,我們可以 在RegEx中 使用 \p{Script=Devanagari}
來匹配所有梵文字符。
//The following matches multiple hindi character
/^\p{Script=Devanagari}+$/u.test('??????'); //true
//PS:there are 3 hindi characters h
Similarly, Unicode database groups all Greek characters under Script_Extensions
(and Script
) property with the value Greek
. So we can search for all Greek characters using Script_Extensions=Greek
or Script=Greek
.
類似地,Unicode數據庫將Script_Extensions
(和Script
)屬性下的所有希臘字符Script_Extensions
為值Greek
。 因此,我們可以使用Script_Extensions=Greek
或Script=Greek
搜索所有希臘字符。
That is, we can use: \p{Script=Greek}
in the RegEx to match all Greek characters.
也就是說,我們可以 在RegEx中 使用 \p{Script=Greek}
來匹配所有希臘字符。
//The following matches a single Greek character
/\p{Script_Extensions=Greek}/u.test('π'); // true
Further, the Unicode database stores various types of Emojis under the boolean properties Emoji
, Emoji_Component
, Emoji_Presentation
, Emoji_Modifier
, and Emoji_Modifier_Base
with property values as `true`. So we can search for all Emojis by simply selecting Emoji
to be true.
此外,Unicode數據庫在布爾屬性Emoji
, Emoji_Component
, Emoji_Presentation
, Emoji_Modifier
和Emoji_Modifier_Base
的布爾屬性下存儲各種類型的Emoji
,其屬性值為“ Emoji_Modifier_Base
”。 因此,我們只需選擇正確的Emoji
即可搜索所有Emoji
。
That is, we can use: \p{Emoji}
,\Emoji_Modifier
and so on to match various kinds of Emojis.
也就是說,我們可以使用: \p{Emoji}
, \Emoji_Modifier
等來匹配各種 \p{Emoji}
。
The following example will make it all clear.
下面的示例將使一切變得清楚。
//The following matches an Emoji character
/\p{Emoji}/u.test('??'); //true//The following fails because yellow emojis don't need/have Emoji_Modifier!
/\p{Emoji}\p{Emoji_Modifier}/u.test('??'); //false//The following matches an emoji character\p{Emoji} followed by \p{Emoji_Modifier}
/\p{Emoji}\p{Emoji_Modifier}/u.test('?🏽'); //true//Explaination:
//By default the victory emoji is yellow color.
//If we use a brown, black or other variations of the same emoji, they are considered
//as variations of the original Emoji and are represented using two unicode characters.
//One for the original emoji, followed by another unicode character for the color.
//
//So in the below example, although we only see a single brown victory emoji,
//it actually uses two unicode characters, one for the emoji and another
// for the brown color.
//
//In Unicode database, these colors have Emoji_Modifier property.
//So we need to use both \p{Emoji} and \p{Emoji_Modifier} to properly and
//completely match the brown emoji.
/\p{Emoji}\p{Emoji_Modifier}/u.test('?🏽'); //true
Lastly, we can use capital "P”(\P
) escape character instead of small p (\p
), to negate the matches.
最后,我們可以使用大寫的“ P”( \P
)轉義字符代替小p( \p
) 來否定匹配項。
References:
參考文獻:
ECMAScript 2018 Proposal
ECMAScript 2018提案
https://mathiasbynens.be/notes/es-unicode-property-escapes
https://mathiasbynens.be/notes/es-unicode-property-escapes
8. Promise.prototype.finally() (8. Promise.prototype.finally())
finally()
is a new instance method that was added to Promise. The main idea is to allow running a callback after either resolve
or reject
to help clean things up. The finally
callback is called without any value and is always executed no matter what.
finally()
是已添加到Promise中的新實例方法。 主要思想是允許在resolve
或reject
之后運行回調,以幫助清理問題。 finally
回調將被調用而沒有任何值,并且無論如何始終執行。
Let’s look at various cases.
讓我們看看各種情況。
9.異步迭代 (9. Asynchronous Iteration)
This is an *extremely* useful feature. Basically it allows us to create loops of async code with ease!
這是*非常有用的功能。 基本上,它使我們可以輕松地創建異步代碼循環!
This feature adds a new “for-await-of” loop that allows us to call async functions that return promises (or Arrays with a bunch of promises) in a loop. The cool thing is that the loop waits for each Promise to resolve before doing to the next loop.
此功能添加了一個新的“ for-await-of”循環,該循環允許我們調用異步函數,該函數在循環中返回promise(或帶有promise的Arrays)。 很棒的事情是,循環在執行下一個循環之前等待每個Promise解決。
That’s pretty much it!
差不多了!
If this was useful, please click the clap 👏 button down below a few times to show your support! ??? 🙏🏼
如果這樣做有用,請幾次單擊下面的拍手👏按鈕以表示支持! 🙏🏼
我的其他帖子 (My Other Posts)
https://medium.com/@rajaraodv/latest
https://medium.com/@rajaraodv/latest
ECMAScript 2015+相關文章 (Related ECMAScript 2015+ posts)
Check out these useful ECMAScript 2015 (ES6) tips and tricks
查看這些有用的ECMAScript 2015(ES6)提示和技巧
5 JavaScript “Bad” Parts That Are Fixed In ES6
ES6中修復的5個JavaScript“不良”部分
Is “Class” In ES6 The New “Bad” Part?
ES6中的“類”是新的“不良”部分嗎?
翻譯自: https://www.freecodecamp.org/news/here-are-examples-of-everything-new-in-ecmascript-2016-2017-and-2018-d52fa3b5a70e/