本文是 ES6 系列的第二篇,前一篇《ES6 蜻蜓點水》概要介紹了ES6,這一篇標題之因此叫「舊瓶新酒」,是想介紹那些原來就被普遍使用的JS對象,例如String、Array,ES6對這些JS對象擴展了一些頗有用的新方法。本文會介紹一些我的以爲頗有用的方法,並不會覆蓋全部ES6新增方法。git
本文將介紹如下JS對象:es6
Stringgithub
Numbersegmentfault
Array數組
Objectbabel
這裏有ES6特性的兼容對比表格,方面你們查看本文說起的ES6特性在各個運行環境的兼容狀況。模塊化
1) Unicode 表示法 函數
JavaScript容許採用\uxxxx
形式表示一個字符,支持\u0000—\uFFFF
之間的字符,對於超過\uFFFF
的字符,使用兩個字節的形式:this
'\uD842\uDFB7' // '?'
ES6 在此基礎上作了改進,引入大括號來表示一個碼點(code point)prototype
'\u{20BB7}' // '?" '\u0041' // 'A' '\u{41}' // 'A'
除此以外,還擴展了String.prototype.codePointAt()
和String.fromCodePoint()
方法,能夠識別超出\uFFFF
的碼點。
2) codePointAt()
之前經過charCodeAt()
獲取字符碼點,可是對超出\uFFFF
的雙字節字符則會出錯,只能獲取第一個字節的碼點,ES6新增了codePointAt()
方法來獲取字符的unicode碼點,能夠正確識別雙字節的字符。
"?".charCodeAt(0) // 55362 "?".charCodeAt(0).toString(16) // 'd842' "?".codePointAt(0) // 134071 "?".codePointAt(0).toString(16) // '20bb7'
3) String.fromCodePoint()
此方法用於從碼點返回對應字符,支持識別雙字節字符。
String.fromCodePoint(0x20bb7) // '?'
ES6 的字符串實現了 Iterator 遍歷器接口,所以能夠用 for...of
循環遍歷字符串。
for (let codePoint of 'foo') { console.log(codePoint) } // 'f' // 'o' // 'o'
與普通 for
循環最大的不一樣是,for...of
循環遍歷的單位是字符碼點(code point),而 for
循環遍歷的單位是字符單元(code unit)
var text = String.fromCodePoint(0x20BB7); for (let i = 0; i < text.length; i++) { console.log(text[i]); } // ' ' // ' ' for (let i of text) { console.log(i); } // '?'
1) includes()
之前沒法直接判斷一個字符串是否另外一個字符串的子字符串,只能經過indexOf()
方法來判斷。
'hello world'.indexOf('hello') // 0 'hello world'.indexOf('es6') // -1
在 ES6 中能夠直接使用includes()
直接判斷。
'hello world'.includes('hello') // true 'hello world'.includes('es6') // false
includes() 還能夠接收第二個參數,表示從第幾位開始檢索
'hello world'.includes('hello', 1) // false
2) startsWith(), endsWith()
在ES6中還能夠直接判斷一個字符串是否以某個特定子串開頭,或是否以某個特定子串結尾。
之前只能用String.prototype.indexOf()
和RegExp.prototype.test()
判斷:
'hello world'.indexOf('hello') // 0 /world$/.test('hello world') // true
在ES6中能夠這麼寫
'hello world'.startsWith('hello') // true 'hello world'.endsWith('world') // true
startsWith() 和 endsWith() 還能夠接收第二個參數,表示從第幾位開始檢索
'hello world'.startsWith('world', 6) // true 'hello world'.endsWith('hello', 5) // true
3) repeat()
此方法返回一個新字符串,表示將原字符串重複n次。
'hello'.repeat(2) // 'hellohello'
ES6 裏能夠用0b
前綴表示二進制,用0o
表示八進制
console.log(0b1100) // 12 console.log(0o1100) // 576
ES6 新增了指數運算符 **
console.log(2 ** 4) // 16 console.log(Math.pow(2, 4)) // 16
Number.isFinite()
與全局函數 isFinite()
的區別是,只判斷數值,全部非數值均返回false,而isFinite()
會先將非數值的值轉爲數值
Number.isFinite(16) // true Number.isFinite('16') // false isFinite(16) // true isFinite('16') // true Number.isFinite(Infinity) // false
與 Number.isFinite()
相似,Number.isNaN()
值判斷數值,全部非數值均返回false
Number.isNaN(NaN) // true Number.isNaN('a') // false isNaN('a') // true
Number.parseInt(), Number.parseFloat()
與全局函數parseInt(), parseFloat()
做用相同,放到 Number 對象的靜態方法,目的是逐步減小全局性方法,使得語言逐步模塊化。
Number.isInteger()
用來判斷一個值是否爲整數。
Number.isInteger(16) // true Number.isInteger(16.2) // false Number.isInteger('16') // false
因爲 Javascript 的浮點運算不是精確的,存在偏差。Number.EPSILON
表示一個極小常量,當浮點運算的偏差小於這個常量時,就認爲浮點運算結果是正確的。
0.1 + 0.2 // 0.30000000000000004 0.1 + 0.2 - 0.3 < Number.EPSILON // true
用 Number.isSafeInteger()
函數判斷整數是否在-2^53到2^53之間,由於JavaScript可以準確表示的整數範圍在-2^53到2^53之間。
Number.isSafeInteger(16) // true Number.isSafeInteger(2 ** 54) // false
Array.from()
用於將對象轉換爲數組。
例如將字符串轉爲數組:
Array.from('hello') // ["h", "e", "l", "l", "o"]
例如將DOM的NodeList轉爲數組:
var elm = document.querySelectorAll('div'); Array.from(elm).forEach(function (div) { // do something });
Array.from()
函數還能夠接受第二個參數,用於處理數組的每一個元素。
Array.from('123', (x) => x * x) // [1, 4, 9]
Array.of
用於構造一個新數組,能夠取代 new Array()
。由於當 new Array()
一個參數和多個參數時,行爲不一致。
new Array(3) // [ , , ] new Array(3, 2, 1) // [3, 2, 1] Array.of(3) // [3] Array.of(3, 2, 1) // [3, 2, 1]
用於監聽(取消監聽)數組的變化,指定回調函數。在ES7中已被建議撤銷。
find()
遍歷數組直到找到符合條件的元素,返回該元素,若找不到則返回undefined。findIndex()
用法跟 find()
相似,但返回值是元素的位置,若找不到則返回-1
['hello', 'world', 'es6'].find(function(item) { if(item === 'world') { return true; } }); // 'world' [1, 0, 2].findIndex(function(item) { if(item === 0) { return true; } }); // 1
find()
和findIndex()
還能夠接收第二個參數,用於指定回調函數的 this
上下文
這三個方法都返回一個遍歷器對象,用於遍歷數組。entries()
用於遍歷數組鍵值對,keys()
用於遍歷數組下標,values()
用於遍歷數組的值。
for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
直接寫變量
{x, y} // 等同於 { x: x, y: y }
直接寫函數
{ say() { console.log('I am ES6'); } } // 等同於 { say: function() { console.log('I am ES6'); } }
ES6 支持在字面量定義對象時使用表達式做爲屬性名。
var world = 'es6'; var obj = { hello: 1, [world]: 2 }; // {hello: 1, es6: 2}
Object.assign()
方法拷貝一個對象屬性到目標對象上。
Object.assign({}, {a: 1}) // {a: 1} Object.assign({a: 1}, {a: 2}) // {a: 2}
對於嵌套的對象,Object.assign的處理方法是替換,而不是添加。
var target = { a: { b: 'hello', c: 'world' } }; var source = { a: { b: 'es6' } }; Object.assign(target, source); // { a: { b: 'es6' } }