ES6 舊瓶新酒

本文是 ES6 系列的第二篇,前一篇《ES6 蜻蜓點水》概要介紹了ES6,這一篇標題之因此叫「舊瓶新酒」,是想介紹那些原來就被普遍使用的JS對象,例如String、Array,ES6對這些JS對象擴展了一些頗有用的新方法。本文會介紹一些我的以爲頗有用的方法,並不會覆蓋全部ES6新增方法。git

本文將介紹如下JS對象:es6

  • Stringgithub

  • Numbersegmentfault

  • Array數組

  • Objectbabel

這裏有ES6特性的兼容對比表格,方面你們查看本文說起的ES6特性在各個運行環境的兼容狀況。模塊化

String

Unicode 表示法

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'

Number

二進制和八進制

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()

Number.isFinite() 與全局函數 isFinite() 的區別是,只判斷數值,全部非數值均返回false,而isFinite() 會先將非數值的值轉爲數值

Number.isFinite(16)
// true
Number.isFinite('16')
// false

isFinite(16)
// true
isFinite('16')
// true

Number.isFinite(Infinity)
// false

Number.isNaN()

Number.isFinite() 相似,Number.isNaN() 值判斷數值,全部非數值均返回false

Number.isNaN(NaN)
// true
Number.isNaN('a')
// false
isNaN('a')
// true

Number.parseInt(), Number.parseFloat()

Number.parseInt(), Number.parseFloat()與全局函數parseInt(), parseFloat()做用相同,放到 Number 對象的靜態方法,目的是逐步減小全局性方法,使得語言逐步模塊化。

Number.isInteger()

Number.isInteger() 用來判斷一個值是否爲整數。

Number.isInteger(16)
// true
Number.isInteger(16.2)
// false
Number.isInteger('16')
// false

Number.EPSILON

因爲 Javascript 的浮點運算不是精確的,存在偏差。Number.EPSILON 表示一個極小常量,當浮點運算的偏差小於這個常量時,就認爲浮點運算結果是正確的。

0.1 + 0.2
// 0.30000000000000004

0.1 + 0.2 - 0.3 < Number.EPSILON
// true

Number.isSafeInteger()

Number.isSafeInteger() 函數判斷整數是否在-2^53到2^53之間,由於JavaScript可以準確表示的整數範圍在-2^53到2^53之間。

Number.isSafeInteger(16)
// true

Number.isSafeInteger(2 ** 54)
// false

Array

Array.from()

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()

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]

Array.observe

用於監聽(取消監聽)數組的變化,指定回調函數。在ES7中已被建議撤銷。

find(), findIndex()

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()

這三個方法都返回一個遍歷器對象,用於遍歷數組。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"

Object

Object 的簡潔表示法

直接寫變量

{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() 方法拷貝一個對象屬性到目標對象上。

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' } }

參考

相關文章
相關標籤/搜索