1.let和const命令
暫時性死區(qū)的本質(zhì)就是键俱,只要一進入當(dāng)前作用域兰绣,所要使用的變量就已經(jīng)存在了,但是不可獲取编振,只有等到聲明變量的那一行代碼出現(xiàn)缀辩,才可以獲取和使用該變量。
- let命令在代碼塊內(nèi)有效(for循環(huán)中使用效果好)踪央。
- let命令不存在變量提升臀玄。
- let命令在代碼塊內(nèi)有效(for循環(huán)中使用效果好)。
- 暫時性死區(qū)(temporal dead zone畅蹂,簡稱 TDZ):在塊級作用域中健无,如果在let和const聲明了變量之前使用變量,就會報錯液斜。
- let命令不允許在相同作用域重復(fù)聲明一個變量累贤。
- {}:塊級作用域可以任意嵌套叠穆。
- 塊級作用域的出現(xiàn),實際上使得獲得廣泛應(yīng)用的立即執(zhí)行函數(shù)表達式(IIFE)不再必要了臼膏。
- 塊級作用域是一個語句硼被,將多個操作封裝在一起,沒有返回值讶请。
- const聲明一個只讀的常量祷嘶。一旦聲明,常量的值就不能改變夺溢,聲明之后,立即初始化烛谊。
- const實際上保證的风响,并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址不得改動丹禀。對于簡單類型的數(shù)據(jù)(數(shù)值状勤、字符串、布爾值)双泪,值就保存在變量指向的那個內(nèi)存地址持搜,因此等同于常量。但對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組)焙矛,變量指向的內(nèi)存地址葫盼,保存的只是一個指針,const只能保證這個指針是固定的村斟,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的贫导,就完全不能控制了。因此蟆盹,將一個對象聲明為常量必須非常小心孩灯。
- 變量聲明的6中方法。var逾滥,function峰档,let,const寨昙,import讥巡,class
變量的解構(gòu)賦值
- 數(shù)組的解構(gòu)賦值
let [a, b, c] = [1, 2, 3];
- 對象的解析賦值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
- 字符串的解析賦值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
- 數(shù)值和布爾值的解構(gòu)賦值
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
- 函數(shù)參數(shù)的解構(gòu)賦值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
字符串的擴展
- 字符的 Unicode 表示法
- codePointAt()
- String.fromCodePoint()
- 字符串的遍歷器接口
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
- at()
'abc'.at(0) // "a"
'??'.at(0) // "??"
- normalize():用來將字符的不同表示方法統(tǒng)一為同樣的形式,這稱為Unicode正規(guī)化毅待。
'abc'.at(0) // "a"
'??'.at(0) // "??"
- includes(), startsWith(), endsWith()
includes():返回布爾值尚卫,表示是否找到了參數(shù)字符串。
startsWith():返回布爾值尸红,表示參數(shù)字符串是否在源字符串的頭部吱涉。
endsWith():返回布爾值刹泄,表示參數(shù)字符串是否在源字符串的尾部。- repeat()
'x'.repeat(3) // "xxx"
- padStart()怎爵,padEnd() :padStart()用于頭部補全特石,padEnd()用于尾部補全。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padEnd(4, 'ab') // 'xaba'
- 模板字符串:模板字符串(template string)是增強版的字符串鳖链,用反引號(`)標識姆蘸。它可以當(dāng)作普通字符串使用,也可以用來定義多行字符串芙委,或者在字符串中嵌入變量逞敷。
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
正則的擴展
- u修飾符:用來正確處理大于\uFFFF的Unicode字符。
- y修飾符:y修飾符的作用與g修飾符類似灌侣,也是全局匹配推捐,后一次匹配都從上一次匹配成功的下一個位置開始。不同之處在于侧啼,g修飾符只要剩余位置中存在匹配就可牛柒,而y修飾符確保匹配必須從剩余的第一個位置開始,這也就是“粘連”的涵義痊乾。
- sticky屬性:表示是否設(shè)置了y修飾符皮壁。
var r = /hello\d/y;
r.sticky // true
- flags屬性:會返回正則表達式的修飾符。
/abc/ig.source
// "abc"
/abc/ig.flags
// 'gi'
數(shù)值的擴展
- 二進制和八進制表示法:前綴0b(或0B)和0o(或0O)表示
- Number.isFinite():用來檢查一個數(shù)值是否為有限的哪审。 Number.isNaN():用來檢查一個值是否為NaN蛾魄。
- ES6將全局方法parseInt()和parseFloat(),移植到Number對象上面协饲,行為完全保持不變畏腕。
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
- Number.isInteger()用來判斷一個值是否為整數(shù)。
數(shù)組的擴展
- Array.from方法用于將兩類對象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對象(array-like object)和可遍歷(iterable)的對象茉稠。
- Array.of方法用于將一組值描馅,轉(zhuǎn)換為數(shù)組。
- 數(shù)組實例的copyWithin方法而线,在當(dāng)前數(shù)組內(nèi)部铭污,將指定位置的成員復(fù)制到其他位置(會覆蓋原有成員),然后返回當(dāng)前數(shù)組膀篮。也就是說嘹狞,使用這個方法,會修改當(dāng)前數(shù)組誓竿。
- find方法磅网,用于找出第一個符合條件的數(shù)組成員。它的參數(shù)是一個回調(diào)函數(shù)筷屡,所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù)涧偷,直到找出第一個返回值為true的成員簸喂,然后返回該成員。findIndex方法的用法與find方法非常類似燎潮,返回第一個符合條件的數(shù)組成員的位置喻鳄,如果所有成員都不符合條件,則返回-1确封。
- fill方法使用給定值除呵,填充一個數(shù)組。
- eys()是對鍵名的遍歷爪喘、values()是對鍵值的遍歷颜曾,entries()是對鍵值對的遍歷。
- Array.prototype.includes方法返回一個布爾值腥放,表示某個數(shù)組是否包含給定的值泛啸,與字符串的includes方法類似。
函數(shù)
- ES6 允許為函數(shù)的參數(shù)設(shè)置默認值秃症。
- ES6 引入 rest 參數(shù)(形式為“...變量名”),用于獲取函數(shù)的多余參數(shù)吕粹,這樣就不需要使用arguments對象了种柑。
- 擴展運算符:擴展運算符(spread)是三個點(...)。
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
- name 屬性
function foo() {}
foo.name // "foo"
- ES6允許使用“箭頭”(=>)定義函數(shù)匹耕。
- 綁定this:函數(shù)綁定運算符是并排的兩個雙冒號(::)聚请。
foo::bar;
// 等同于
bar.bind(foo);
- 尾調(diào)用(Tail Call)是函數(shù)式編程的一個重要概念,本身非常簡單稳其,一句話就能說清楚驶赏,就是指某個函數(shù)的最后一步是調(diào)用另一個函數(shù)。
對象的擴展
- 屬性的簡潔表示法:
var foo = 'bar';
var baz = {foo};
baz // {foo: "bar"}
- 屬性名表達式
- 方法的 name 屬性
- Object.is():ES6提出“Same-value equality”(同值相等)算法既鞠,用來解決這個問題煤傍。
- Object.assign():Object.assign方法用于對象的合并,將源對象(source)的所有可枚舉屬性嘱蛋,復(fù)制到目標對象(target)蚯姆。
- 屬性的遍歷:for...in,Object.keys(obj)洒敏,Object.getOwnPropertyNames(obj)龄恋,Object.getOwnPropertySymbols(obj),Reflect.ownKeys(obj)凶伙。
- proto屬性(前后各兩個下劃線)郭毕,用來讀取或設(shè)置當(dāng)前對象的prototype對象。
- Object.keys()函荣,Object.values()显押,Object.entries()
ES5 引入了Object.keys方法扳肛,返回一個數(shù)組,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名煮落。
Object.values方法返回一個數(shù)組敞峭,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。
Object.entries方法返回一個數(shù)組蝉仇,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對數(shù)組旋讹。
symbol
- Symbol:保證每個屬性的名字都是獨一無二的,這樣就從根本上防止屬性名的沖突轿衔,Symbol值通過Symbol函數(shù)生成沉迹。
- Symbol.for():有時,我們希望重新使用同一個Symbol值害驹,Symbol.for方法可以做到這一點鞭呕。它接受一個字符串作為參數(shù),然后搜索有沒有以該參數(shù)作為名稱的Symbol值宛官。如果有葫松,就返回這個Symbol值,否則就新建并返回一個以該字符串為名稱的Symbol值底洗。
- Symbol.keyFor:返回一個已登記的 Symbol 類型值的key腋么。
Set和Map數(shù)據(jù)結(jié)構(gòu)
- Set:ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set。它類似于數(shù)組亥揖,但是成員的值都是唯一的珊擂,沒有重復(fù)的值。Set 本身是一個構(gòu)造函數(shù)费变,用來生成 Set 數(shù)據(jù)結(jié)構(gòu)摧扇。add(),delete(), has(), clear()
- WeakSet:WeakSet結(jié)構(gòu)與Set類似挚歧,也是不重復(fù)的值的集合扛稽。無法引用WeakSet的成員,因此WeakSet是不可遍歷的昼激。
- Map:ES6提供了Map數(shù)據(jù)結(jié)構(gòu)庇绽。它類似于對象,也是鍵值對的集合橙困,但是“鍵”的范圍不限于字符串瞧掺,各種類型的值(包括對象)都可以當(dāng)作鍵。size(), set(), get(), has(), delete(), clear()
- WeakMap:WeakMap結(jié)構(gòu)與Map結(jié)構(gòu)基本類似凡傅,唯一的區(qū)別是它只接受對象作為鍵名(null除外)辟狈,不接受其他類型的值作為鍵名,而且鍵名所指向的對象,不計入垃圾回收機制哼转。
Proxy
- Proxy 可以理解成明未,在目標對象之前架設(shè)一層“攔截”,外界對該對象的訪問壹蔓,都必須先通過這層攔截趟妥,因此提供了一種機制,可以對外界的訪問進行過濾和改寫佣蓉。Proxy 這個詞的原意是代理披摄,用在這里表示由它來“代理”某些操作,可以譯為“代理器”勇凭。
- Proxy 實例的方法
Proxy 對象的所有用法疚膊,都是上面這種形式,不同的只是handler參數(shù)的寫法虾标。其中寓盗,new Proxy()表示生成一個Proxy實例,target參數(shù)表示所要攔截的目標對象璧函,handler參數(shù)也是一個對象傀蚌,用來定制攔截行為。
var proxy = new Proxy(target, handler);
Promise
Promise 是異步編程的一種解決方案蘸吓,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大喳张。then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)美澳。因此可以采用鏈式寫法,即then方法后面再調(diào)用另一個then方法摸航。
Iterator(遍歷器)的概念
JavaScript原有的表示“集合”的數(shù)據(jù)結(jié)構(gòu)制跟,主要是數(shù)組(Array)和對象(Object),ES6又添加了Map和Set酱虎。這樣就有了四種數(shù)據(jù)集合雨膨,用戶還可以組合使用它們,定義自己的數(shù)據(jù)結(jié)構(gòu)读串,比如數(shù)組的成員是Map聊记,Map的成員是對象。這樣就需要一種統(tǒng)一的接口機制恢暖,來處理所有不同的數(shù)據(jù)結(jié)構(gòu)排监。
Iterator的遍歷過程是這樣的。
- 創(chuàng)建一個指針對象杰捂,指向當(dāng)前數(shù)據(jù)結(jié)構(gòu)的起始位置舆床。也就是說,遍歷器對象本質(zhì)上,就是一個指針對象挨队。
- 第一次調(diào)用指針對象的next方法谷暮,可以將指針指向數(shù)據(jù)結(jié)構(gòu)的第一個成員。
- 第二次調(diào)用指針對象的next方法盛垦,指針就指向數(shù)據(jù)結(jié)構(gòu)的第二個成員湿弦。
- 不斷調(diào)用指針對象的next方法,直到它指向數(shù)據(jù)結(jié)構(gòu)的結(jié)束位置腾夯。
每一次調(diào)用next方法颊埃,都會返回數(shù)據(jù)結(jié)構(gòu)的當(dāng)前成員的信息。具體來說俯在,就是返回一個包含value和done兩個屬性的對象竟秫。其中,value屬性是當(dāng)前成員的值跷乐,done屬性是一個布爾值肥败,表示遍歷是否結(jié)束。
Generator
執(zhí)行 Generator 函數(shù)會返回一個遍歷器對象愕提,也就是說馒稍,Generator 函數(shù)除了狀態(tài)機,還是一個遍歷器對象生成函數(shù)浅侨。返回的遍歷器對象纽谒,可以依次遍歷 Generator 函數(shù)內(nèi)部的每一個狀態(tài)。
形式上如输,Generator 函數(shù)是一個普通函數(shù)鼓黔,但是有兩個特征。一是不见,function關(guān)鍵字與函數(shù)名之間有一個星號澳化;二是,函數(shù)體內(nèi)部使用yield語句稳吮,定義不同的內(nèi)部狀態(tài)(yield在英語里的意思就是“產(chǎn)出”)缎谷。
需要注意的是,yield語句后面的表達式灶似,只有當(dāng)調(diào)用next方法列林、內(nèi)部指針指向該語句時才會執(zhí)行,因此等于為JavaScript提供了手動的“惰性求值”(Lazy Evaluation)的語法功能酪惭。
- 協(xié)程的 Generator 函數(shù)實現(xiàn):Generator 函數(shù)是協(xié)程在 ES6 的實現(xiàn)希痴,最大特點就是可以交出函數(shù)的執(zhí)行權(quán)(即暫停執(zhí)行)。