es6的各種小紅書

看各種帖子和阮一峯老師的es6做了些自己的核心記錄,用來回顧

解構賦值

從對象解構

 const AritleDetail = {
        articleId: 'at_001',
        authName: 'mega_galaxy'
    }
    
const { articleId, authName } = AritleDetail;

articleId // 'at_001'
authName  // 'mega_galaxy'

從數組解構

AritleDetail = ['2019-05-23', 1087];

//則解構 時會把數組 某位置的值 賦值 給左邊 相同位置的 變量
const [publishDate, wordSummary] = AritleDetail;

設定默認值

假設後端返回的數據 AritleDetail 的結構長這樣:
    const AritleDetail = {
        authName: '',
        publicshDate: undefined,
        content: null
    }
//後臺數據返回爲空時設置默認值
const { authName = '未知作者', publicshDate = '2019-01-01', content = '文章內容爲空'} = AritleDetail;

find方法

用於找出第一個符合條件的數組成員。它的參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值爲true的成員,然後返回該成員。如果沒有符合條件的成員,則返回undefined。

	let arr =[1, 4, -5, 10]
	arr.find((v) => v < 0)
	// -5

遍歷數組查找到第一個符合的值就return該值,可能不會循環完整

findIndex方法

findIndex方法的用法與find方法非常類似,返回第一個符合條件的數組成員的index值,如果所有成員都不符合條件,則返回-1

數組實例的 entries(),keys() 和 values()

可以用for…of循環進行遍歷,唯一的區別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。

	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"

數組實例的 includes()

表示某個數組是否包含給定的值,與字符串的includes方法類似。

	[1, 2, 3].includes(2)     // true
	[1, 2, 3].includes(4)     // false
	[1, 2, NaN].includes(NaN) // true

字符串repeat()

repeat方法返回一個新字符串,表示將原字符串重複n次。

	'x'.repeat(3) // "xxx"
	'hello'.repeat(2) // "hellohello"
	'na'.repeat(0) // ""

字符串padStart(),padEnd()

引入了字符串補全長度的功能。如果某個字符串不夠指定長度,會在頭部或尾部補全。padStart()用於頭部補全,padEnd()用於尾部補全。
padStart()和padEnd()一共接受兩個參數,第一個參數是字符串補全生效的最大長度,第二個參數是用來補全的字符串。

'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'

'abc'.padStart(10, '0123456789') //如果用來補全的字符串與原字符串,兩者的長度之和超過了最大長度,則會截去超出位數的補全字符串。
// '0123456abc'

padStart()的常見用途是爲數值補全指定位數。下面代碼生成 10 位的數值字符串。

'1'.padStart(10, '0') // "0000000001"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

字符串trim()

去除空格

Object.assign

Object.assign方法用於對象的合併,將源對象(source)的所有可枚舉屬性,複製到目標對象(target)Object.assign方法的第一個參數是目標對象,後面的參數都是源對象

	const target = { a: 1 };
	
	const source1 = { b: 2 };
	const source2 = { c: 3 };
	
	Object.assign(target, source1, source2);
	target // {a:1, b:2, c:3}

擴展運算符(…)

擴展運算符(spread)是三個點(…)。它好比 rest 參數的逆運算,將一個數組轉爲用逗號分隔的參數序列。

console.log(...[1, 2, 3])
// 1, 2, 3

該運算符主要用於函數調用。
function push(array, ...items) {
  array.push(...items);
}

對象深拷貝

如果想完整克隆一個對象,還拷貝對象原型的屬性,可以採用下面的寫法。

// 寫法一
const clone1 = {
  __proto__: Object.getPrototypeOf(obj),
  ...obj
};

// 寫法二
const clone2 = Object.assign(
  Object.create(Object.getPrototypeOf(obj)),
  obj
);

// 寫法三
const clone3 = Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
)

上面代碼中,寫法一的__proto__屬性在非瀏覽器的環境不一定部署,因此推薦使用寫法二和寫法三。

js的 == 和 === 缺陷

相等運算符 == 和嚴格相等運算符 ===。它們都有缺點,前者會自動轉換數據類型,後者的NaN不等於自身,以及+0等於-0。
ES6 提出“Same-value equality”(同值相等)算法,用來解決這個問題。Object.is就是部署這個算法的新方法。它用來比較兩個值是否嚴格相等,與嚴格比較運算符( === )的行爲基本一致。

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

不同之處只有兩個:一是+0不等於-0,二是NaN等於自身。

Object.assign()

Object.assign方法用於對象的合併,將源對象(source)的所有可枚舉屬性,複製到目標對象(方法實行的是淺拷貝,而不是深拷貝)

const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

//Object.assign可以用來處理數組,但是會把數組視爲對象。
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]

如果目標對象與源對象有同名屬性,或多個源對象有同名屬性,則後面的屬性會覆蓋前面的屬性。

Object.keys(),Object.values(),Object.entries()

Object.keys()
ES5 引入了Object.keys方法,返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名。

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作爲遍歷一個對象的補充手段,供for…of循環使用。

let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };

for (let key of Object.keys(obj)) {
  console.log(key); // 'a', 'b', 'c'
}

for (let value of Object.values(obj)) {
  console.log(value); // 1, 2, 3
}

for (let [key, value] of Object.entries(obj)) {
  console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}

set

Set函數可以接受一個數組(或者具有 iterable 接口的其他數據結構)作爲參數,用來初始化。

const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
  console.log(i);
}

Set.prototype.size:返回Set實例的成員總數。
add(value):添加某個值,返回 Set 結構本身。
delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
has(value):返回一個布爾值,表示該值是否爲Set的成員。
clear():清除所有成員,沒有返回值。

Array.from方法可以將 Set 結構轉爲數組。
set數組去重

function dedupe(array) {
  return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

Promise

下面代碼創造了一個Promise實例。

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise實例生成以後,可以用then方法分別指定resolved狀態和rejected狀態的回調函數。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});
getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});

上面的代碼使用then方法,依次指定了兩個回調函數。第一個回調函數完成以後,

會將返回結果作爲參數,傳入第二個回調函數。

Generator 函數(生成器)

Generator 函數有多種理解角度。語法上,首先可以把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。

執行 Generator 函數會

返回一個遍歷器對象

,也就是說,Generator 函數除了狀態機,還是一個遍歷器對象生成函數。返回的遍歷器對象,可以依次遍歷 Generator 函數內部的每一個狀態。
形式上,Generator 函數是一個普通函數,但是有兩個特徵。一是,function關鍵字與函數名之間有一個星號;二是,函數體內部使用yield表達式,定義不同的內部狀態(yield在英語裏的意思就是“產出”)。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

上面代碼定義了一個 Generator 函數helloWorldGenerator,它內部有兩個yield表達式(hello和world),即該函數有三個狀態:hello,world 和 return 語句(結束執行)。

然後,Generator 函數的調用方法與普通函數一樣,也是在函數名後面加上一對圓括號。不同的是,調用 Generator 函數後,該函數並不執行,返回的也不是函數運行結果,而是一個指向內部狀態的指針對象,遍歷器對象(Iterator Object)。
下一步,必須調用遍歷器對象的next方法,使得指針移向下一個狀態。也就是說,每次調用next方法,內部指針就從函數頭部或上一次停下來的地方開始執行,直到遇到下一個yield表達式(或return語句)爲止。換言之,Generator 函數是分段執行的,yield表達式是暫停執行的標記,而next方法可以恢復執行。

遍歷器對象的next方法的運行邏輯如下。

(1)遇到yield表達式,就暫停執行後面的操作,並將緊跟在yield後面的那個表達式的值,作爲返回的對象的value屬性值。

(2)下一次調用next方法時,再繼續往下執行,直到遇到下一個yield表達式。

(3)如果沒有再遇到新的yield表達式,就一直運行到函數結束,直到return語句爲止,並將return語句後面的表達式的值,作爲返回的對象的value屬性值。

(4)如果該函數沒有return語句,則返回的對象的value屬性值爲undefined。

Iterator(遍歷器)的概念

遍歷器(Iterator)是這樣一種機制,它是一種接口,爲各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數據結構的所有成員)。

Iterator 的作用有三個:
一是爲各種數據結構,提供一個統一的、簡便的訪問接口;
二是使得數據結構的成員能夠按某種次序排列;
三是 ES6 創造了一種新的遍歷命令for…of循環,Iterator 接口主要供for…of消費。

Iterator 的遍歷過程是這樣的。

(1)創建一個指針對象,指向當前數據結構的起始位置。也就是說,遍歷器對象本質上,就是一個指針對象。

(2)第一次調用指針對象的next方法,可以將指針指向數據結構的第一個成員。

(3)第二次調用指針對象的next方法,指針就指向數據結構的第二個成員。

(4)不斷調用指針對象的next方法,直到它指向數據結構的結束位置。

每一次調用next方法,都會返回數據結構的當前成員的信息。具體來說,就是返回一個包含value和done兩個屬性的對象。其中,value屬性是當前成員的值,done屬性是一個布爾值,表示遍歷是否結束。

下面是一個next方法返回值的例子。

var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

ES6的Module

js的各種模塊方式

//導出方式
module.exports = {
 stat,
 exists,
 readFile 
};

// ES6模塊
import { stat, exists, readFile } from 'fs';
// ES6模塊整體輸出
import * as fs from 'fs'

// CommonJS 模塊
const fs = require('fs')
  • CommonJS 加載的是一個對象(即module.exports屬性),該對象只有在腳本運行完纔會生成。而 ES6模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。

CommonJS先加載文件,後加載CommonJS內容,CommonJS模塊輸出的是被輸出值的拷貝,相當於將CommonJS模塊複製寫入加載的文件js中(異步);ES6模塊隨代碼一起加載(同步)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章