es6語言特性的總結(jié)(2)

數(shù)組

ES6中對于數(shù)據(jù)做了進(jìn)一步的增強(qiáng),以便能夠更加方便地創(chuàng)建數(shù)組以及操作數(shù)組。

創(chuàng)建數(shù)組

Array.of

該方法用于將一組值轉(zhuǎn)換為數(shù)組。

Array.of(1); [1]
Array.of(3, 21, 22); [3,21,22]

這個(gè)方法的出現(xiàn)主要是為了彌補(bǔ)之前數(shù)組構(gòu)造函數(shù)的一些缺陷:

Arry(); // []
Array(3); // [undefined, undefined, undefined]

你會發(fā)現(xiàn)在使用單個(gè)數(shù)值參數(shù)的時(shí)候,那個(gè)參數(shù)被構(gòu)造器作為數(shù)組長度而進(jìn)行初始化。而兩個(gè)參數(shù)以上的時(shí)候,則返回由參數(shù)構(gòu)成的數(shù)組。而 Array.of() 方法總會創(chuàng)建一個(gè)包含所有傳入?yún)?shù)的數(shù)組,而不管參數(shù)的數(shù)量與類型。

Array.from

該方法通常用于將類似數(shù)組的對象以及可遍歷對象轉(zhuǎn)換成數(shù)組。你可以將NodeList,Set,Map等等解構(gòu)進(jìn)行數(shù)組的轉(zhuǎn)換。

利用該方法的第二個(gè)參數(shù),你可以指定一個(gè)回調(diào)函數(shù),用于對數(shù)組進(jìn)行映射操作。

//arguments為函數(shù)傳入的參數(shù)
let args = Array.from(arguments, value => value + 1);
//等同于
let args = Array.from(arguments).map(value => value + 1);

該方法的第三個(gè)參數(shù)是上下文,在映射函數(shù)中如果需要使用this,需要手動(dòng)傳入該參數(shù)。

在ES6中, Class 語法允許我們?yōu)閮?nèi)置類型(比如 Array)和自定義類新建子類(比如叫 SubArray)。這些子類也會繼承父類的靜態(tài)方法,比如 SubArray.from(),調(diào)用該方法后會返回子類 SubArray 的一個(gè)實(shí)例,而不是 Array 的實(shí)例。

實(shí)例方法

fill

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

[1,2,3].fill(1); //用1填充數(shù)組所有項(xiàng) [1,1,1]
[1,2,3].fill(10, 2); //從索引2開始用10填充數(shù)組 [1, 2, 10]
[1,2,3,4].fill(0, 2, 3);//從索引2到索引3之間開始用0填充數(shù)組 [1,2,0,4]

find/findIndex

該方法的參數(shù)是一個(gè)回調(diào)函數(shù),用于查找數(shù)組中滿足回調(diào)函數(shù)測試的第一個(gè)值或者第一個(gè)索引(index)。

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

該方法用來復(fù)制自身元素,然后填充進(jìn)數(shù)組里。

補(bǔ)充

針對可迭代的對象,ES6提供了三個(gè)新的方法:entries,keys, values分別用于返回鍵值對、鍵名、鍵值的迭代器,可以使用for...of語法進(jìn)行訪問。而數(shù)組的鍵名其實(shí)就是它的索引值。


字符串

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

模板字面量

在ES6中,我們可以使用反引號(` )來包裹普通字符串。
在ES5,我們?nèi)绻梢粋€(gè)多行的字符串,通常要使用+連字符,而現(xiàn)在只要使用反引號就可以了。

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

標(biāo)簽化模板

模板標(biāo)簽(template tag)能對模板字面量進(jìn)行轉(zhuǎn)換并返回最終的字符串值,標(biāo)簽在模板的起始處被指定。標(biāo)簽實(shí)際上就是一個(gè)函數(shù),它被調(diào)用時(shí)接收需要處理的模板字面量數(shù)據(jù),然后進(jìn)行處理后返回一個(gè)字符串。這個(gè)函數(shù)的第一個(gè)參數(shù)是一個(gè)數(shù)組,包含被JS解釋過的字面量字符串,隨后的參數(shù)是每個(gè)替換位的解釋值。

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}.`; 

在上面這個(gè)例子中,literials被賦值為['My name is ', [, and my age is ], [.]],而substutions則是['scq000', 12],即用來替換的值。你可以在這個(gè)函數(shù)中,利用這兩個(gè)信息對字符串做進(jìn)一步的加工。

另外,有個(gè)內(nèi)置的String.raw標(biāo)簽,可以直接獲取模板字面量的原始值,即轉(zhuǎn)義之前的值。

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

字符串實(shí)例方法

對于字符串的實(shí)例方法上,新增了一些比較常用的方法。

  1. includes: 在給定文本存在于字符串中的任意位置時(shí)會返回 true ,否則返回 false 。
  2. startsWith: 在給定文本出現(xiàn)在字符串起始處時(shí)返回 true ,否則返回 false 。
  3. endsWith: 在給定文本出現(xiàn)在字符串結(jié)尾處時(shí)返回 true ,否則返回 false 。

需要注意的是,與之前indexOf等方法不同,以上這些實(shí)例方法的參數(shù)不能傳入正則表達(dá)式,否則會拋出錯(cuò)誤。

  1. repeat: 接受一個(gè)參數(shù)作為字符串的重復(fù)次數(shù),返回一個(gè)將初始字符串重復(fù)指定次數(shù)的新字符串。

符號

從ES6開始,引入了第6個(gè)基本數(shù)據(jù)類型:符號(Symbol)。 它是一種特殊的、不可變的數(shù)據(jù)類型,可以作為對象屬性的標(biāo)識符使用。

創(chuàng)建符號值

const name = Symbol(); //注意這里不能用new,因?yàn)镾ymbol是基本數(shù)據(jù)類型
const aname = Symbol('aname'); //提供的這個(gè)參數(shù)主要用來調(diào)試
typeof name //"Symbol"

使用符號值

可以在任何能使用“計(jì)算屬性名”的場合使用符號。

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對象定義了兩個(gè)符號類型屬性,并將它們設(shè)為只讀的。利用這種方式,特別適合創(chuàng)建對象私有成員。

暴露內(nèi)部方法

利用Symbol的一些屬性,可以針對對象的一些內(nèi)部行為進(jìn)行操作。

  1. Symbol.iterator: 一個(gè)返回對象默認(rèn)迭代器的方法,使用for...of
  2. Symbol.match: 一個(gè)用于對字符串進(jìn)行匹配的方法,也用于確定一個(gè)對象是否可以作為正則表達(dá)式使用。使用String.prototype.match
  3. Symbol.replace:一個(gè)替換匹配字符串的子串的方法.使用String.prototype.replace
  4. Symbol.search
  5. Symbol.split
  6. Symbol.hasInstance: 一個(gè)確定一個(gè)構(gòu)造器對象識別的對象是否為它的實(shí)例的方法。使用 instanceof.
  7. Symbol.isConcatSpreadable: 一個(gè)布爾值,表明一個(gè)對象是否應(yīng)該flattened為它的數(shù)組元素。使用Array.prototype.concat().
  8. Symbol.unscopables: 擁有和繼承屬性名的一個(gè)對象的值被排除在與環(huán)境綁定的相關(guān)對象外。
  9. Symbol.species: 一個(gè)用于創(chuàng)建派生對象的構(gòu)造器函數(shù)。.
  10. Symbol.toPrimitive: 一個(gè)將對象轉(zhuǎn)化為基本數(shù)據(jù)類型的方法。
  11. Symbol.toStringTag: 用于對象的默認(rèn)描述的字符串值。使用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這個(gè)屬性,使得對象iterator獲得了迭代器的能力。因此,可以對這個(gè)對象使用for...of的語法進(jìn)行迭代操作。

Set與Map

ES6中增加了兩個(gè)新的數(shù)據(jù)結(jié)構(gòu),Set和Map,補(bǔ)充了原本數(shù)組的一些不足之處。Set 是不包含重復(fù)值的列表,而Map 則是鍵與相對應(yīng)的值的集合。

Set

Set是一種無重復(fù)值的有序列表。
創(chuàng)建一個(gè)Set很簡單,只要使用new關(guān)鍵字就可以了。Set的構(gòu)造器實(shí)際上可以接受任何可迭代對象作為參數(shù)。在構(gòu)造器內(nèi)部,會使用迭代器來提取參數(shù)中的值。

let set1 = new Set(); //創(chuàng)建一個(gè)空的集合 Set {}
let set2 = new Set([1,2,3]); //創(chuàng)建一個(gè)包含三個(gè)元素的集合, Set {1, 2, 3}
let set3 = new Set([1,2,3,4,4]); //創(chuàng)建一個(gè)去重后的集合, Set {1, 2, 3}

針對Set,主要提供了以下幾個(gè)方法:

  1. add: 能向 Set 中添加項(xiàng)目
  2. has: 測試某個(gè)值是否存在于 Set 中
  3. delete: 來移除單個(gè)值
  4. clear: 來將所有值從 Set 中移除
    還提供了一個(gè)size屬性用于判斷集合長度
let set = new Set([1,2,3,4,5,6]);
set.add(3); //由于3已經(jīng)在集合里了,并不會添加新項(xiàng)
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 {}

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

Set的遍歷

同數(shù)組一樣,作為可迭代的數(shù)據(jù)結(jié)構(gòu),ES6提供了forEach的方法對其進(jìn)行遍歷。你也可以使用,for...of的語法進(jìn)行。

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的每一項(xiàng)同時(shí)被認(rèn)為鍵和值,因此,key和value其實(shí)是一致的。如果想在回調(diào)函數(shù)中使用 this ,你可以給 forEach() 傳入一個(gè) this 值作為第三個(gè)參數(shù)。你也可以使用箭頭函數(shù)來達(dá)到同等的效果。

轉(zhuǎn)換成數(shù)組

要將Set轉(zhuǎn)換成數(shù)組,可以像下面這樣:

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

使用擴(kuò)展運(yùn)算符可以更簡單地將 Set 轉(zhuǎn)換回?cái)?shù)組。

Map

Map與Set相似,數(shù)據(jù)結(jié)構(gòu)中存儲著鍵值對。實(shí)例方法與Set相同的部分是has,delete,clear。你可以調(diào)用 set() 方法并給它傳遞一個(gè)鍵與一個(gè)關(guān)聯(lián)的值,來給 Map 添加項(xiàng);此后使用鍵名來調(diào)用 get() 方法便能提取對應(yīng)的值。

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語法,其中的回調(diào)函數(shù)同樣是接收三個(gè)參數(shù):value,key,context。當(dāng)然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的實(shí)例中,則是采用了強(qiáng)引用的方式,只要SetMap的實(shí)例存在,其中所存儲的對象就無法被垃圾回收機(jī)制回收,從而無法釋放內(nèi)存。利用WeakSet和WeakMap的弱引用方式,則可以在內(nèi)存管理上有著更加容易優(yōu)化的空間。

系列一
系列三

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、ES6簡介 ? 歷時(shí)將近6年的時(shí)間來制定的新 ECMAScript 標(biāo)準(zhǔn) ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,212評論 8 25
  • 三,字符串?dāng)U展 3.1 Unicode表示法 ES6 做出了改進(jìn),只要將碼點(diǎn)放入大括號,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,674評論 0 8
  • 1.概述 ES5的對象屬性名都是字符串,這容易造成屬性名的沖突。比如,你使用了一個(gè)他人提供的對象,但又想為這個(gè)對象...
    趙然228閱讀 883評論 2 10
  • 1 該流的總會流下來 想走的怎么也留不住 眼淚的奧義 2 你喜歡看《愛格》嗎 故事沒有結(jié)局 我們卻可以 3 天空飄...
    柳林風(fēng)聲叮鈴鈴閱讀 195評論 0 1
  • 如果世界上只有一個(gè)你,你就不再是你了,因?yàn)闆]有了他們。 如果世界給你三天光陰,你也不是你了,因?yàn)槟阍跉v史的時(shí)間軸上...
    Baby_fly閱讀 314評論 0 2

友情鏈接更多精彩內(nèi)容