ES6語言特性的總結(2)

數組

ES6中對於數據作了進一步的加強,以便可以更加方便地建立數組以及操做數組。javascript

建立數組

Array.of

該方法用於將一組值轉換爲數組。前端

Array.of(1); [1]
Array.of(3, 21, 22); [3,21,22]複製代碼

這個方法的出現主要是爲了彌補以前數組構造函數的一些缺陷:java

Arry(); // []
Array(3); // [undefined, undefined, undefined]複製代碼

你會發如今使用單個數值參數的時候,那個參數被構造器做爲數組長度而進行初始化。而兩個參數以上的時候,則返回由參數構成的數組。而 Array.of() 方法總會建立一個包含全部傳入參數的數組,而無論參數的數量與類型。正則表達式

Array.from

該方法一般用於將相似數組的對象以及可遍歷對象轉換成數組。你能夠將NodeList,Set,Map等等解構進行數組的轉換。數組

利用該方法的第二個參數,你能夠指定一個回調函數,用於對數組進行映射操做。微信

//arguments爲函數傳入的參數
let args = Array.from(arguments, value => value + 1);
//等同於
let args = Array.from(arguments).map(value => value + 1);複製代碼

該方法的第三個參數是上下文,在映射函數中若是須要使用this,須要手動傳入該參數。數據結構

在ES6中, Class 語法容許咱們爲內置類型(好比 Array)和自定義類新建子類(好比叫 SubArray)。這些子類也會繼承父類的靜態方法,好比 SubArray.from(),調用該方法後會返回子類 SubArray 的一個實例,而不是 Array 的實例。app

實例方法

fill

fill() 方法能使用特定值填充數組中的一個或多個元素。frontend

[1,2,3].fill(1); //用1填充數組全部項 [1,1,1]
[1,2,3].fill(10, 2); //從索引2開始用10填充數組 [1, 2, 10]
[1,2,3,4].fill(0, 2, 3);//從索引2到索引3之間開始用0填充數組 [1,2,0,4]複製代碼

find/findIndex

該方法的參數是一個回調函數,用於查找數組中知足回調函數測試的第一個值或者第一個索引(index)。ide

let numbers = [1,342,342,22, 34, 35];
console.log(numbers.find(n => n > 35));         // 342
console.log(numbers.findIndex(n => n > 33)); // 1複製代碼

copyWithin

該方法用來複制自身元素,而後填充進數組裏。

補充

針對可迭代的對象,ES6提供了三個新的方法:entries,keys, values分別用於返回鍵值對、鍵名、鍵值的迭代器,可使用for...of語法進行訪問。而數組的鍵名其實就是它的索引值。

let set = new Set();
set.add(1);
set.add(2);
set.add(3);
for(let value of set.entries()) {
    console.log(value);
}

//輸出 [1,1] [2,2] [3,3]複製代碼

字符串

字符串的操做層面,ES6提供了模板對象、多行字符串的支持。

模板字面量

在ES6中,咱們可使用反引號(` )來包裹普通字符串。
在ES5,咱們若是要生成一個多行的字符串,一般要使用+連字符,而如今只要使用反引號就能夠了。

var str = `Courses are provided in MOOC format with course material available online, mostly as videos complemented with exercise and example files. All throughout the course, a technical expert will be available online to provide help and answer your questions. Each course takes approximately 6 to 7 hours to complete, depending on your proficiency, and must be completed within one week.`;複製代碼

另外,咱們能夠在字符串模板中製造替換位,從而使用一些變量來填充咱們的模板。

var name = 'scq000';
var str = `Hello, ${name}`; // Hello,scq000複製代碼

###標籤化模板

模板標籤(template tag)能對模板字面量進行轉換並返回最終的字符串值,標籤在模板的起始處被指定。標籤實際上就是一個函數,它被調用時接收須要處理的模板字面量數據,而後進行處理後返回一個字符串。這個函數的第一個參數是一個數組,包含被JS解釋過的字面量字符串,隨後的參數是每一個替換位的解釋值。

function tag(literals, ...substitutions) {
  let result = '';
  console.log(literals);
  console.log(substitutions);
  return result;
}
var name = 'scq000';
var age = 12;

let msg = tag`My name is ${name}, and my age is ${age}.`;複製代碼

在上面這個例子中,literials被賦值爲['My name is ', [, and my age is ], [.]],而substutions則是['scq000', 12],即用來替換的值。你能夠在這個函數中,利用這兩個信息對字符串作進一步的加工。

另外,有個內置的String.raw標籤,能夠直接獲取模板字面量的原始值,即轉義以前的值。

let msg = String.raw`hello$1\nworld`console.log(msg); //hello$1\nworld複製代碼

字符串實例方法

對於字符串的實例方法上,新增了一些比較經常使用的方法。

  1. includes: 在給定文本存在於字符串中的任意位置時會返回 true ,不然返回 false 。
  2. startsWith: 在給定文本出如今字符串起始處時返回 true ,不然返回 false 。
  3. endsWith: 在給定文本出如今字符串結尾處時返回 true ,不然返回 false 。

須要注意的是,與以前indexOf等方法不一樣,以上這些實例方法的參數不能傳入正則表達式,不然會拋出錯誤。

  1. repeat: 接受一個參數做爲字符串的重複次數,返回一個將初始字符串重複指定次數的新字符串。

符號

從ES6開始,引入了第6個基本數據類型:符號(Symbol)。 它是一種特殊的、不可變的數據類型,能夠做爲對象屬性的標識符使用。

建立符號值

const name = Symbol(); //注意這裏不能用new,由於Symbol是基本數據類型
const aname = Symbol('aname'); //提供的這個參數主要用來調試
typeof name //"Symbol"複製代碼

使用符號值

能夠在任何能使用「計算屬性名」的場合使用符號。

let firstName = Symbol('first name');
let lastName = Symbol('last name');

let person = {
  [firstName]: 'scq'
};
Object.defineProperty(person, firstName, { writable: false });

Object.defineProperties(person, {
  [lastName]: {
    value: '000',
    writable: false
  }
});複製代碼

上面的例子,爲person對象定義了兩個符號類型屬性,並將它們設爲只讀的。利用這種方式,特別適合建立對象私有成員。

暴露內部方法

利用Symbol的一些屬性,能夠針對對象的一些內部行爲進行操做。

  1. Symbol.iterator: 一個返回對象默認迭代器的方法,使用for...of
  2. Symbol.match: 一個用於對字符串進行匹配的方法,也用於肯定一個對象是否能夠做爲正則表達式使用。使用String.prototype.match
  3. Symbol.replace:一個替換匹配字符串的子串的方法.使用String.prototype.replace
  4. Symbol.search
  5. Symbol.split
  6. Symbol.hasInstance: 一個肯定一個構造器對象識別的對象是否爲它的實例的方法。使用 instanceof.
  7. Symbol.isConcatSpreadable: 一個布爾值,代表一個對象是否應該flattened爲它的數組元素。使用Array.prototype.concat().
  8. Symbol.unscopables: 擁有和繼承屬性名的一個對象的值被排除在與環境綁定的相關對象外。
  9. Symbol.species: 一個用於建立派生對象的構造器函數。.
  10. Symbol.toPrimitive: 一個將對象轉化爲基本數據類型的方法。
  11. Symbol.toStringTag: 用於對象的默認描述的字符串值。使用Object.prototype.toString().

功能比較多,就不一一說明了。下面就以iterator來講明一下使用方法:

var iterator = {
  [Symbol.iterator]() {
    return {
      start: 0,
      next() {
        if(this.start < 10) {
          return {value: this.start ++, done: false}
        }else {
          return {value: undefined, done: true}
        }
      }
    }
  }
};

for(var value of iterator) {
  console.log(vlaue);
}複製代碼

上面的例子利用了Symbol.iterator這個屬性,使得對象iterator得到了迭代器的能力。所以,能夠對這個對象使用for...of的語法進行迭代操做。

Set與Map

ES6中增長了兩個新的數據結構,Set和Map,補充了本來數組的一些不足之處。Set 是不包含重複值的列表,而Map 則是鍵與相對應的值的集合。

Set

Set是一種無重複值的有序列表。
建立一個Set很簡單,只要使用new關鍵字就能夠了。Set的構造器實際上能夠接受任何可迭代對象做爲參數。在構造器內部,會使用迭代器來提取參數中的值。

let set1 = new Set(); //建立一個空的集合 Set {}
let set2 = new Set([1,2,3]); //建立一個包含三個元素的集合, Set {1, 2, 3}
let set3 = new Set([1,2,3,4,4]); //建立一個去重後的集合, Set {1, 2, 3}複製代碼

針對Set,主要提供瞭如下幾個方法:

  1. add: 能向 Set 中添加項目
  2. has: 測試某個值是否存在於 Set 中
  3. delete: 來移除單個值
  4. clear: 來將全部值從 Set 中移除
    還提供了一個size屬性用於判斷集合長度
let set = new Set([1,2,3,4,5,6]);
set.add(3); //因爲3已經在集合裏了,並不會添加新項
set.add('nihao'); // Set {1,2,3,4,5,6,'nihao'}
set.has(3); //true
set.delete(3); // Set {1,2,4,5,6,'nihao'}
set.clear(); // Set {}複製代碼

注意的是,當一個屬性被添加到 set 對象時,它的值也被設爲true。而在 Set 內部的比較使用了Object.is()方法,來判斷兩個值是否相等。

Set的遍歷

同數組同樣,做爲可迭代的數據結構,ES6提供了forEach的方法對其進行遍歷。你也可使用,for...of的語法進行。

let set = new Set(['a','b','c']);
set.forEach((value, key) => console.log('Value: ' + value + ' Key: ' + key));
//Value: a Key: a
//Value: b Key: b
//Value: c Key: c複製代碼

因爲Set的每一項同時被認爲鍵和值,所以,key和value實際上是一致的。若是想在回調函數中使用 this ,你能夠給 forEach() 傳入一個 this 值做爲第三個參數。你也可使用箭頭函數來達到同等的效果。

轉換成數組

要將Set轉換成數組,能夠像下面這樣:

let set = new Set([1,2,3,4,5]);
Array.from(set); //[1,2,3,4,5]
[...set]; //[1,2,3,4,5]複製代碼

使用擴展運算符能夠更簡單地將 Set 轉換回數組。

Map

Map與Set類似,數據結構中存儲着鍵值對。實例方法與Set相同的部分是has,delete,clear。你能夠調用 set() 方法並給它傳遞一個鍵與一個關聯的值,來給 Map 添加項;此後使用鍵名來調用 get() 方法便能提取對應的值。

let map = new Map();
map.set('key1', 'value1'); //Map {"key1" => "value1"}
map.set('key2', 'value2'); //Map {"key1" => "value1", "key2" => "value2"}
map.get('key1'); //value1
map.has('key2'); //true
map.delete('key1'); //刪除成功會返回true
map.has('key1'); //false
map.clear(); //清空全部複製代碼

而對於map的遍歷可使用forEach語法,其中的回調函數一樣是接收三個參數:value,key,context。固然context是可選的。

let map = new Map();
map.set('key1', 'value1'); 
map.set('key2', 'value2'); 
map.forEach((value,key) => console.log(value));
//value1, value2複製代碼

WeakSet和WeakMap

WeakMap和WeakSet同樣,存儲了是對象的弱引用方式。而Set和Weak的實例中,則是採用了強引用的方式,只要SetMap的實例存在,其中所存儲的對象就沒法被垃圾回收機制回收,從而沒法釋放內存。利用WeakSet和WeakMap的弱引用方式,則能夠在內存管理上有着更加容易優化的空間。

系列三請點這裏


本文對你有幫助?歡迎掃碼加入前端學習小組微信羣:

相關文章
相關標籤/搜索