ES6 標準入門第2版 筆記


看這本書是在markdown在做的筆記,更友好的閱讀方式訪問: github es6.md(https://github.com/EarlyBirdss/Study-Diary/blob/master/es6.md)

ES6

https://babeljs.io/repl/ 在線轉碼


let


let 聲明一個變量, 只在let命令所在的代碼塊有效(非常適合在for循環中)

let沒有變量提升, 這意味著typeof不再是百分比安全的操作

只要在塊級作用域中存在let命令,它所在聲明的變量就綁定(binding)在這個區域, 不受外界影響

暫時性死區:在代碼塊內使用let命令聲明變量之前, 該變量都是不可用的

let 不允許在相同作用域內重復聲明同一個變量

可以使用let很方便的塊級作用域 (IIFE)


const

用來聲明常量,一旦聲明,其值不可修改(很多規則跟let一樣,理解成繼承吧)

必須一聲明就立即初始化,不能留到以后賦值

對于復雜的數據結構(對象,數組), const只能保證保存該數據的地址不發生變化,不能保證其內部值發生變化。(可以使用Object.freeze()凍結對象)


變量的解構賦值

解構: ES6按照一定模式,從數組和對象中提取值,對變量進行賦值,這稱為解構

數組

var [a,b,c] = [1,2,3]; //a=1,b=2,c=3

var [head,,third,...tail]=[1,2,3,4]; //tail=[4]

var [foo] = [];//如果解構不成功,變量的值就等于undefined

let [a,[b],d] = [1,[2,3],4]; //b=2;不完全解構,解構依然可以成功

如果等號右邊不是數組(可遍歷的結構)就會報錯;

默認值:

let [x,y=1] = [0]; //x=0,y=1;

let [x,y=1,z] = [0, undefined,2]; //x=0,y=1,z=2;(必須使用undefined/,因為es6內部使用嚴格等===)

惰性求值, 如果默認值是表達式, 只用用的時候才求值

對象

對象沒有次序,變量必須和屬性同名或使用以下方式,才能取得正確的值

var {foo:baz} = {foo: 1, bar: 2}; //baz=1;

字符串

因為字符串自帶length屬性,

let {length: len} = 'jifag';

字符串被轉換為類似數組的對象

const [a,b,c,d,e] = 'hello'; //a='h',b='e'...

解構可以嵌套

var {p: [x,{y}]} = {p:['hello',{y:'world'}]}; // x='hello',y='world';此時p是模式不是變量名

函數參數的解構賦值

酷!

圓括號問題

對于編譯器來說, 一個式子是模式還是表達式,沒有辦法從一開始就知道,帶來的問題就是, 如果模式中出現圓括號怎么處理。

建議: 不要在模式中放圓括號

幾種情況下在模式中使用圓括號會報錯

用途!!!!

交換變量的值 [x,y] = [y,x];

獲取從函數返回的多個值 var [a,b,c] = test(); //test return [1,2,3];

函數參數的定義

eg1: 參數是有序值function f([x,y,z]){}; f([1,2,3])

eg2: 參數是無序值function f({x,y,z}){}; f({x:1,y:2,z=3})

提取json數據

函數參數的默認值(好用!!!)

let {log, sin, cos} = Math; //很方便就能把想用的拿出來


reg

u修飾符: 用于處理4個字節的utf=16編碼, 如(根本打不出來, 瀏覽器跟markdown也顯示不了好伐, 這個問題忽略)

y修飾符: ‘粘連’ 跟g一樣是全局匹配, 但g是從上一次匹配的剩余位置開始匹配,y限制了只能從剩余位置的第一位匹配

var str = 'aaa_aa_a', g = /a+/g, y = /a+/y;

g.exec(str); //執行兩次, ['aaa'],['aa']

y.exec(str); //執行兩次, ['aaa'],null


Array

() //將類數組(array like)對象和可遍歷的對象轉化為真正的數組,接受第二次參數類似于數組的map函數Array.from({'0':1, '1': 2, '2': 3}, x => x * x) //[1,4,9];

擴展運算符 (...)

Array.of() //將一組值轉化為數組 Array.of(1,2,3) //[1,2,3]

數組實例 Array.prototype.copyWithin(target, start = 0, end = this.length): 在數組內部將指定位置的成員復制到其他位置(覆蓋)

數組實例 Array.prototype.find()和findIndex();

find(function(value, index, arr){})有點像filter, find只找到第一個符合條件的值就返回這個值 findIndex返回該值的位置

數組實例 Array.prototype.fill(value, start = 0, end = this.length) //很方便的初始化空數組,如果不是空數組, 數組中已有的元素將被重置 new Array(3).fill(0) //[0,0,0]

數組實例 Array.prototype.entries(),keys(),values() 返回遍歷器對象

數組實例 Array.includes() 返回布爾值

數據推導 [for (year of years) if (year > 2000) year];


函數

rest參數(...變量名): 替代arguments function add(...value){}

擴展運算符(...) 像reset參數的逆運算

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

替代數組的apply方法

合并數組 [1,2,...more] //more=[3,4];

與解構賦值結合 const [first, ...rest] = [1,2,3,4];//first=1,rest=[2,3,4];

箭頭函數

var sum = (num1, num2) => num1 + num2;

如果函數內代碼語句多于一行,要用大括號括起來,并使用return返回

簡化回調函數 [1,2,3].map(x => x * x); //[1,4,9]; [6,1,8].sort((a,b) => a - b); //[1,6,8]; const number = (...nums) => nums; // number(1,2,3)=>[1,2,3]


對象

屬性的簡潔表示法 let obj = {x,test(){}}

屬性名表達式 let obj = {['a' + 'b']: 'ab'}

屬性名表達式與簡潔表示法不能同時使用,會報錯

Object.is()用來比較兩個值是否嚴格相等,與嚴格等(===)的行為基本一致,不同之處只有兩個

1. +0不等于-0

2. NaN等于自身

Object.assign(): 用來將源對象的所有可枚舉屬性賦值到目標對象 //Object.assign(target, source1, source2);


Symbol

(研究了大半天終于發現意義在哪里,現在表示當前對象的屬性有三種 obj.a、obj['a']、obj[a],一二種是ES5的字符串屬性名,第三種是Symbol類型,這樣就實現唯一的標識了)

ES6引用一種新的原始數據類型Symbol表示獨一無二的值

let s = Symbol();typeof s;//symbol沒有‘new’

let s = Symbol('foo'),a={};a[s] = function(){};//不能使用點運算符(a.s),不加引號(a['s']);

Symbol的參數是沒有實際意義的,只表示對Symbol實例的描述,主要是為了方便區分

symbol可以用來定義一組常量,保證這組常量的值都是不相等的

魔術字符串:在代碼之中多次出現、與代碼行程強耦合的某一個集體的字符串或數值。

消除魔術字符串的常用方便就是把它寫成一個常量, 此時比較適合用Symbol

Symbol類型的屬性名,不會出現在for...in、for...of遍歷中,也不會被Object.keys(),Object.getOwnPropertyNames()返回。也不是私有屬性。Object.getOwnPropertySymbols可以獲取指定對象的所有Symbol屬性名

Symbol.for(name):重新使用同一個symbol值

var s1 = Symbol.for('foo'), s2 = Symbol.for('foo');s1 === s2; //true

var s1 = Symbol('foo'), s2 = Symbol.for('foo');s1 === s2; //false

內置的Symbol值


Proxy和Reflect

proxy用于修改某些操作的默認行為,等同于在語言層面做出修改,屬于“元程序”(對編程語言進行編程)。代理器,攔截器

作為構造函數Proxy接受兩個參數,第一個參數是所要代理的目標對象,第二個參數是配置對象(包含有處理函數),要使Proxy起作用,必須針對Proxy實例進行操作,而不是針對目標對象

var proxy = new Proxy({},{

get: function(target, property){

return 35;

}

});

proxy.time; //35

set();利用Proxy,可以將讀取屬性的操作轉變為執行某個函數,從而實現屬性的鏈式調用

var pipe = (function() {

var pipe;

return function(value) {

get: function(pipeObject, fnName) {

if(fnName == 'get') {

return pipe.reduce(function(val, fn) {

return fn(val);

}, value);

}

pipe.push(window[fnName]);

return pipeObject;

}

}

});

Proxy中設置set方法可以攔截某個屬性的賦值操作

let validator = {

set: function(obj, prop, value) {

if(prop === 'age'){

if(!Number.isInteger(value)) {

throw(new TypeError('The age is not an integer'));

}

if(value > 200) {

throw new RangeError('The age seems invalid');

}

}

obj[prop] = value;

}

}

let person = new Proxy({}, validator);

person.age = 100;

person.age = 400;//報錯

apply()方法攔截函數的調用

has()方法可以隱藏某些屬性不被in操作符發現

construct()方法用來攔截new命令

deleteProperty()方法攔截delete操作

defineProperty()方法攔截Object.defineProperty();

enumerate()方法攔截for...in循環

ownKeys()方法攔截Object.keys()

Reflect 將Object某些語言層面的方法部署到Reflect之中


set

新的數據結構,類似于數組,成員的值都是唯一的,沒有重復的值

set函數可以接受一個數組(或類數組)let set = new Set([1,2,3,3]); [...set]; //[1,2,3]

屬性和方法set.prototype.size ,add(value), delete(value), has(value), clear()

遍歷操作 keys(),values(),entries(),forEach();前三個返回遍歷器。set結構只有鍵值沒有鍵名,keys的返回值等于values

WeakSet 內部成員只能是對象,不可遍歷,沒有clear方法,沒有size屬性,引用為存儲dom節點,不必擔心這些節點從文檔移除時會引發內存泄漏(沒有理解……)

Map

理解: Object提供“字符串——值”的對應,Map提供“值——值”的對應

map接收一個數組作為參數,數組的成員為一個個表示鍵值對的數組;

var map = new Map([['name', 'Jack'], ['age', '12']]);

map.size; //2

map.has('name'); //true

map.get('name'); //jack

map.set('gender', 'female'); //

map.delete('age');

map.clear();

WeakMap: 只接收對象為鍵名(null除外)。同樣應用于dom, 部署私有屬性


Iterator

遍歷器,是一種接口,為各種不同的數據結構提供統一的接口的訪問機制,任何數據結構只要部署iterator接口就可以完成遍歷操作

不斷調用next方法 返回({value:value, done: Boolean})

for...of 循環

一個數據結構只要具有Symbol.iterator屬性,就被認為是可遍歷的。調用Symbol.iterator方法就可以得到當前結構的遍歷函數

以下三種結構原生具有iterator接口: 數組, 某些類似數組的對象, set和map結構

var map = new Map([['name', 'aya'], ['gender', 'female']]);

var iter1= map[Symbol.iterator]();

iter1.next(); // Object {"done": false,"value": Array ["name","aya"]}

//類數組調用Symbol.iterator

let iterable = {

'0': 1,

'1': 2,

'2': 3,

length: 3,

[Symbol.iterator]: Array.prototype[Symbol.iterator]

};

let ite =? iterable[Symbol.iterator]();

console.log(ite.next());

對象沒有默認部署iterator接口,是因為哪個屬性先遍歷哪個后遍歷是不確定的。需要開發者手動指定

// 為對象添加Iterator的一個實例

let obj = {

data: ['hello','world'],

[Symbol.iterator]() {

const self = this;

let index = 0;

return {

next() {

if(index < self.data.length) {

return {

value: self.data[index++],

done: false

};

}else {

return {

value: undefined,

done: true

};

}

}

}

}

}

for(let j of obj){

console.log(j);

}

var i = obj[Symbol.iterator]();

i.next(); //'hello';

調用Iterator接口的場合

1. 解構賦值(會默認調用Symbol.iterator方法)

2. 擴展運算符(...)

3. for...of,Array.from(),Map、Set、WeakMap、WeakSet,Promise.all(),Promise.race();

字符串可以訪問Sybmol.iterator方法

for...of(遍歷所有數據結構的統一方法)


Generator

概念: Generator是ES6提供的一種異步編程解決方案。狀態機。執行Generator會返回一個遍歷器對象。

function與函數名之間有一個*號, 函數內部使用yield定義不同的內部狀態

yeild就像是暫停標志,generator.next()執行一次就從就返回一個{value:yeild語句后的值,done:},并暫停向下執行,再執行.next()方法再返回再暫停,直到遇到return語句為止,沒有return就放回{value: undefined, done: true};

yeild后面的表達式,只有當調用next方法,內部指針指向語句時才會執行(惰性求值)

yeild語句不能出現在普通函數中(foreach改為使用for循環),yield語句如果在表達式中,必須加圓括號

next的參數,會被當做上一條yield語句的返回值

for...of,擴展運算符,解構賦值,Array.from

應用

1. 異步操作的同步化表達: 處理異步操作,改寫回調函數

function* main(){

var result = yield request("http://some.url.com");

var resp = JSON.parse(result);

doSomething(resp);

}

2. 在任意對象上部署Iterator接口

function* iterEntries(obj) {

let keys = Object.keys(obj);

for(let i = 0; i < keys.length; i++) {

let key = keys[i];

yield [key, [obj[key]]];

}

}

let testObj = {hello: 'you', world: 'me'};

for(let [key,value] of iterEntries(testObj)){

console.log(key, value);

}

3. 作為數據結構

function* doStuff(){

yield fs.readFile.bind(null, 'hello.txt');

yield fs.readFile.bind(null, 'work.txt');

yield fs.readFile.bind(null, 'as-so-on.txt');

}


Promise

一個對象,用來傳遞異步操作消息

有兩個特點

1. 對象的狀態不受外界干擾。Pending,Resolved(Fulfilled),Rejected。只有異步操作的結果可以決定當前是哪一種狀態。

2. 一旦狀態改變就不會再變,任何時候都可以得到這個結果。promise只能從Pending變為Resolved或Pending變成Rejected。只要一種變化發生就不會再發生變化

實例方法then, catch

Promise.all() 將多個Promise實例包裝成一個新的promise實例 promise.all([p1,p2,p3]);

Promise.race() 同樣將多個promise實例包裝成一個新的promise實例 promise.race([p1,p2,p3]);

區別: all方法,只有參數p全部變成resolved,p才為resolved(rejected同樣);race方法,只要有一個參數變成resolved,p就變為resolved(rejected同樣);

Promise.resolve() 將現有對象轉為promise對象

promise對象可以不帶參數, 如果希望得到一個新的promise對象,可以直接調用 var p = Promise.resolve();

Promise.reject() 返回一個新的promise對象,狀態為Rejected

promise.done() 總是處于回調鏈的尾端,保證拋出任何可能出現的錯誤

promise.finally() 跟promise.done最大的區別的是: finally接受普通函數作為參數,無論如何都會執行


異步操作

ES6的異步編程: 回調函數,事件監聽, 發布/訂閱, Promise對象

異步: 一個任何分為兩段,先執行第一段,然后轉而這行其他認識,等做好準備再回頭執行第二段(不連續的操作)

Thunk函數: 編譯器的傳名調用(如var m = 1; f(m+1),//m+1在f內用到才求值,而不是先求值再調用f(2)),實現往事先將函數放到一個臨時函數中,再將這個臨時函數傳入函數體。這個臨時函數就叫Thunk函數。

js是傳值調用(var m = 1; f(m+1);// 先求值等于2,在調用f(2);Thunk函數替換的不是表達式而是多參數函數,替換為單參數版本,且只接受回調函數作為參數。


Class基本語法

class Point{

constructor(x, y) {

this.x = x;

this.y =y;

}

toString(){

return "x+y= " + this.x + this.y;

}

}

語法糖

類的內部定義的所有方法都是不可枚舉的(跟ES5不同)

constructor方法是類的默認方法,new之后自動調用該函數

如果忘記加new調用Class,會報錯

Class表達式

const MyClass = class Me {

getClassName(){

return Me.name;

}

}

調用時使用new MyClass();Me只供Class的內部代碼使用

不存在變量提升

代碼內部為嚴格模式

extends 實現繼承

class ColorPoint extends Point {

constructor(x, y, color) {

super(x, y);

this.color = color;

}

}

super: 關鍵字,指代了父類的實例(即父類的this對象)

子類必須在constructor方法中調用super, 否則新建實例時會報錯。因為如果不調用super方法,子類就得不到this對象

父類只要用prototype就能被子類繼承, 父類可以是任意函數

對象總是繼承其他對象的,所以可以再任意一個對象中使用super關鍵字

static 靜態方法:在方法前面添加static關鍵字,不會被實例繼承,通過類直接調用

Class只有靜態方法沒有靜態屬性

new.target屬性: 返回new命令所作用的構造函數(在構造函數中使用)


修飾器

類的修飾(Class)

1. 修飾器是一個表達式,用于修改類的行為

2. 修飾器本質是能在編譯時執行的函數

3. 修飾器函數可以接受3個參數: 目標函數(必要),屬性名,該屬性的描述對象

方法的修飾(Class 內部方法)

不能用于普通的函數(因為函數提升)

@autobind @override @deprecate


Module

Class只是語法糖,并沒有解決模塊化問題

Module應對大型程序


編碼風格

塊級作用域let代替var

全局變量應該只能設置常量,優先使用const

靜態字符串使用單引號或反引號,動態字符串使用反引號(`)

解構賦值


使用數組成語對變量賦值,優先使用解構賦值

函數的參數如果是對象的成員,優先使用解構賦值

如果函數返回多個值,優先使用對象的解構賦值而不是數組的解構賦值(便于調整順序)

對象

單行定義的對象,最后一個成員不以逗號結尾;多行定義的對象,最后一個成員使用逗號結尾

對象盡量靜態化,如果屬性不可避免要添加,使用Object.assign()方法

如果對象的屬性名是動態的,創建對象時使用屬性表達式定義

使用擴展運算符(...)復制數組

函數

立即執行函數可以寫成箭頭函數的形式

(() => {

doSomething();

});

使用函數表達式的場合盡量用箭頭函數代替(綁定了this)

簡單的單行的不會復用的函數用箭頭函數

所有的配置項都應該幾種在一個對象,放在最后一個參數,布爾值不可以直接作為參數

總是使用Class代替需要prototype的操作(class寫法更簡潔)

使用extends實現繼承

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容