過了一個五一長期以後,發現2018年都過去一半了,尷尬的計劃卻趕不上時光的變化。javascript
對於這個特性的更改,個人感觸仍是很深的:每當刪除或者添加函數末尾參數時,你不得不在前一個參數的後面刪除或者添加逗號。這種操做很逆天。java
翻翻文檔,其實早在ES5時代已經支持對象尾後逗號的書寫,可是在JSON中是不容許尾後逗號的。web
Tip: JSON.stringify()會自動去掉對象的尾後逗號。app
'咦嘻嘻'.padStart(10, '-') // -------咦嘻嘻
'咦嘻嘻'.padEnd(10, '-') // 咦嘻嘻-------
複製代碼
Tip: 當長度小於字符串自己長度則返回字符串自己dom
看到這個方法,咱們不難會想起在此以前會經過什麼方法去解決此類的問題。ecmascript
('----------' + '咦嘻嘻').slice(-10) // -------咦嘻嘻
複製代碼
在ES6以前咱們能夠經過slice加上固定的padString實現需求,顯然缺點也很明顯:padString的長度不夠靈活。異步
('-'.repeat(10) + '咦嘻嘻').slice(-10) // -------咦嘻嘻
複製代碼
進入ES6以後,咱們能夠經過repeat結合slice實現,固然遠沒有padEnd來得方便。async
繼表情包大戰以後,聊天發表情,評論發表情幾乎是隨處可見。而咱們在字符串的處理中就須要注意emoji表情:函數
const s = '😀'
s.length // 2
複製代碼
因而可知,採用emoji做爲padString時可能出現截斷狀況。fetch
console.log('咦嘻嘻'.padStart(10, s)) // 😀😀😀�咦嘻嘻
複製代碼
雖然這是讓人頭疼的地方,可是emoji也有一些趣事
const s1 = '👨👩👦'
[...s1] // [ '👨', '', '👩', '', '👦' ]
複製代碼
這兩個方法與ES5中的Object.keys()是相似的:
const fruits = {
apple: 2,
orange: 10
}
Object.keys(fruits) // [ 'apple', 'orange' ]
Object.values(fruits) // [ 2, 10 ]
Object.entries(fruits) // [ [ 'apple', 2 ], [ 'orange', 10 ] ]
複製代碼
它們都是獲取枚舉屬性而且不讀取原型上的屬性。
其實到這裏,你們也會想起另外一種遍歷對象的方法:
for (var key in fruits) {
if (fruits.hasOwnProperty(key)) {
console.log(key)
}
}
複製代碼
沒有對比就沒有傷害,for-in就會讀取原型上的屬性,爲了避免出現意想不到的錯誤,一般咱們會使用hasOwnProperty來過濾原型上的屬性。
總結上面這四種遍歷對象的方法,它們一個共同點就是隻獲取枚舉屬性,那麼問題來了,若是想獲取非枚舉屬性怎麼辦呢?
Object.defineProperty(fruits, 'peach', {
value: 18,
enumerable: false
})
Object.getOwnPropertyNames(fruits).filter(item => !fruits.propertyIsEnumerable(item)) // [ 'peach' ]
複製代碼
這裏細心的同窗可能還會發現一個問題:在ES6中爲了解決字符串做爲屬性名帶來的惟一性問題,能夠採用Symbol做爲屬性名使用,那麼Symbol屬性名能書獲取到嗎?
Object.defineProperty(fruits, Symbol('banana'), {
value: 20
})
Object.getOwnPropertySymbols(fruits) // [ Symbol(banana) ]
複製代碼
這裏,忽然想起了香鍋的騷話,固然咱們要的是枚舉屬性、非枚舉屬性以及Symbol屬性:
Reflect.ownKeys(fruits) // [ 'apple', 'orange', 'peach', Symbol(banana) ]
複製代碼
對於這個方法,你們應該不太陌生,由於在ES5中咱們定義對象時會採用:
const obj = {}
Object.defineProperty(obj, 'name', {
value: 'xiaoyun',
enumerable: true,
writable: true,
configurable: true
})
複製代碼
而且會使用getOwnPropertyDescriptor獲取它的描述器屬性:
Object.getOwnPropertyDescriptor(obj, 'name')
複製代碼
Tip: 採用對象字面聲明的屬性的描述器屬性默認爲true,採用defineProperty聲明的屬性的描述器屬性的默認值爲false
因此看到這個方法名,天然就知道它是幹什麼的:
Object.getOwnPropertyDescriptors(obj)
複製代碼
固然,它的出現不只僅是由於這個問題。在ES6中新增的拷貝方法assign,它並不能處理描述器屬性,因此涉及到描述器屬性的對象,不能經過assign來拷貝,因此有了getOwnPropertyDescriptors方法以後,咱們能夠這樣處理設置描述器屬性的對象:
Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj))
複製代碼
對於這個新特性的出現,真是的是讓人眼前一亮。
Tip:實際上async很早就被討論了,以致於不少人認爲它是ES6或者ES7標準,實際上它在2017才被正式列入標準,應該屬於ES8標準。
對於async/await,你必需要知道:
function fetchNumber () {
return new Promise((resolve, reject) => {
setTimeout(_ => {
const num = Number.parseInt(Math.random() * 10)
if (num >= 5) {
resolve(num)
} else {
reject(new Error(`${num} is smaller than 5`))
}
}, 1000)
})
}
async function task () {
try {
const num = await fetchNumber()
return num
} catch (e) {
return Promise.reject(e.message)
}
}
task().then(console.log).catch(console.log)
複製代碼
在使用async時,千萬不要由於它同步的寫法而陷入誤區,具體咱們須要分析咱們的異步,例如:咱們調用多個fetchNumber時,它們之間並無依賴關係,那麼咱們應該這樣寫:
const [num1, num2] = await Promise.all([fetchNumber(), fetchNumber()])
複製代碼
固然若是這兩個方法有相互依賴的關係,那麼就須要:
const num1 = await fetchNumber()
const num2 = await fetchNumber()
複製代碼
對於async的異常處理,基本上仍是採用try/catch的方式,固然也有對try/catch詬病的傳送門。
喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.