[TOC]
參考阮一峰的ECMAScript 6 入門
參考深入淺出ES6
let和const
- let和const都是用來聲明變量的卦睹,用法和var相似
- 用let或const定義的變量只能在let或const命令所在的代碼塊(塊級(jí)作用域)中有效
- es6中新增了塊級(jí)作用域
- ES6 允許塊級(jí)作用域的任意嵌套畦戒,如例2。
- 塊級(jí)作用域的出現(xiàn)分预,實(shí)際上使得獲得廣泛應(yīng)用的立即執(zhí)行函數(shù)表達(dá)式(IIFE)不再必要了兢交,如例3.
//例2
{{{{{let insane = 'Hello World'}}}}};
//外層作用域無法讀取內(nèi)層作用域的變量。
//內(nèi)層作用域可以定義外層作用域的同名變量笼痹。
//例3
// IIFE 寫法
(function () {
var tmp = ...;
...
}());
// 塊級(jí)作用域?qū)懛?{
let tmp = ...;
...
}
- 必須先聲明才能用配喳,沒有預(yù)解釋,只要塊級(jí)作用域內(nèi)存在let命令凳干,它所聲明的變量就“綁定”(binding)這個(gè)區(qū)域晴裹,不再受外部的影響。
未聲明就使用變量報(bào)錯(cuò)的幾種情況
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
上面的代碼會(huì)報(bào)錯(cuò)救赐,因?yàn)榇a塊中用let聲明了一個(gè)變量tmp涧团,這個(gè)tmp就會(huì)跟代碼塊進(jìn)行綁定只磷,而es6中規(guī)定,變量沒有聲明就使用就會(huì)報(bào)錯(cuò)
// 報(bào)錯(cuò)
let x = x;
// ReferenceError: x is not defined
變量x的聲明語句還沒有執(zhí)行完成前泌绣,就去取x的值钮追,導(dǎo)致報(bào)錯(cuò)”x 未定義“。
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 報(bào)錯(cuò)
讓x=y阿迈,但是這時(shí)候y并沒有聲明就使用所以報(bào)錯(cuò)
- let不允許在相同作用域內(nèi)元媚,重復(fù)聲明同一個(gè)變量。
// 報(bào)錯(cuò)
function () {
let a = 10;
let a = 1;
}
// 以下兩行都會(huì)報(bào)錯(cuò)
const message = "Goodbye!";
const age = 30;
//不允許在函數(shù)內(nèi)部重新聲明形參
function func(arg) {
let arg; // 報(bào)錯(cuò)
}
function func(arg) {
{
let arg; // 不報(bào)錯(cuò)
}
}
- let用于定義變量苗沧,const用于定義常量刊棕,const給一個(gè)變量賦值之后就不能給這個(gè)變量重新賦值,會(huì)報(bào)錯(cuò)待逞。
- 對(duì)于const來說甥角,只聲明不賦值,就會(huì)報(bào)錯(cuò)识樱。
- const本質(zhì)上是保證變量所指向的內(nèi)存地址不改變嗤无,對(duì)于基本數(shù)據(jù)類型就是常量,對(duì)于引用數(shù)據(jù)類型牺荠,就是保證變量所對(duì)應(yīng)的內(nèi)存地址的指針不改變翁巍,但是里面的內(nèi)容無法保證;如果想讓對(duì)象的內(nèi)容也不能改變休雌,應(yīng)該使用Object.freeze方法。
const foo = Object.freeze({});
// 常規(guī)模式時(shí)肝断,下面一行不起作用杈曲;
// 嚴(yán)格模式時(shí),該行會(huì)報(bào)錯(cuò)
foo.prop = 123;
//除了將對(duì)象本身凍結(jié)胸懈,對(duì)象的屬性也應(yīng)該凍結(jié)担扑。下面是一個(gè)將對(duì)象徹底凍結(jié)的函數(shù)。
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
- 在ES6中var和function聲明的全局變量趣钱,依舊是window的屬性涌献;let、const首有、class聲明的全局變量燕垃,不屬于window的屬性。
- 在for循環(huán)中使用let聲明變量有一個(gè)特別之處井联,就是循環(huán)語句部分是一個(gè)父作用域卜壕,而循環(huán)體內(nèi)部是一個(gè)單獨(dú)的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
上面代碼輸出了3次abc烙常,這表明函數(shù)內(nèi)部的變量i和外部的變量i是分離的轴捎。
do表達(dá)式
{
let t = f();
t = t * t + 1;
}
上面代碼中,塊級(jí)作用域?qū)蓚€(gè)語句封裝在一起。但是侦副,在塊級(jí)作用域以外侦锯,沒有辦法得到t的值,因?yàn)閴K級(jí)作用域不返回值秦驯,除非t是全局變量尺碰。
要想得到塊級(jí)作用域中的返回值,可以在塊級(jí)作用域之前加上do汇竭,使它變成do表達(dá)式葱蝗。
let x = do {
let t = f();
t * t + 1;
};
上面代碼中,變量x會(huì)得到整個(gè)塊級(jí)作用域的返回值细燎。
關(guān)于ES6中的頂層對(duì)象
ES5中頂層對(duì)象不統(tǒng)一两曼,瀏覽器下是window,node中是global
ES6中
- 全局環(huán)境中玻驻,this會(huì)返回頂層對(duì)象悼凑。但是,Node模塊和ES6模塊中璧瞬,this返回的是當(dāng)前模塊户辫。
- 函數(shù)里面的this,如果函數(shù)不是作為對(duì)象的方法運(yùn)行嗤锉,而是單純作為函數(shù)運(yùn)行渔欢,this會(huì)指向頂層對(duì)象。但是瘟忱,嚴(yán)格模式下奥额,這時(shí)this會(huì)返回undefined。
- 不管是嚴(yán)格模式访诱,還是普通模式垫挨,new Function('return this')(),總是會(huì)返回全局對(duì)象触菜。但是九榔,如果瀏覽器用了CSP(Content Security Policy,內(nèi)容安全政策)涡相,那么eval哲泊、new Function這些方法都可能無法使用。
變量的解構(gòu)賦值
解構(gòu)賦值的規(guī)則是漾峡,只要等號(hào)右邊的值不是對(duì)象或數(shù)組攻旦,就先將其轉(zhuǎn)為對(duì)象
數(shù)組的解構(gòu)賦值
只要等號(hào)兩邊的模式相同,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值,如果解構(gòu)不成功生逸,變量的值就等于undefined牢屋。
let [a, b, c] = [1, 2, 3];
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
- 解構(gòu)賦值允許指定默認(rèn)值且预,默認(rèn)值生效的條件是,解構(gòu)的值是undefined烙无。
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
- ES6 內(nèi)部使用嚴(yán)格相等運(yùn)算符(===)锋谐,判斷一個(gè)位置是否有值。所以截酷,如果一個(gè)數(shù)組成員不嚴(yán)格等于undefined涮拗,默認(rèn)值是不會(huì)生效的。
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
對(duì)象的解構(gòu)賦值
對(duì)象的解構(gòu)與數(shù)組有一個(gè)重要的不同迂苛。數(shù)組的元素是按次序排列的三热,變量的取值由它的位置決定;而對(duì)象的屬性沒有次序三幻,變量必須與屬性同名就漾,才能取到正確的值。
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
對(duì)象的解構(gòu)賦值是下面形式的簡寫,也就是說,對(duì)象的解構(gòu)賦值的內(nèi)部機(jī)制念搬,是先找到同名屬性抑堡,然后再賦給對(duì)應(yīng)的變量。真正被賦值的是后者朗徊,而不是前者首妖,前者只是要匹配的模式,后者才是變量爷恳。
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
使用對(duì)象的解構(gòu)賦值時(shí)有缆,變量的聲明和賦值是一體的,對(duì)于let和const來說温亲,變量不能重新聲明妒貌,所以一旦賦值的變量以前聲明過,就會(huì)報(bào)錯(cuò)铸豁。
- 對(duì)象的解構(gòu)也可以指定默認(rèn)值,默認(rèn)值生效的條件是菊碟,對(duì)象的屬性值嚴(yán)格等于undefined节芥。
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
字符串的解構(gòu)賦值
字符串解構(gòu)賦值的時(shí)候會(huì)被轉(zhuǎn)成類數(shù)組
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
類似數(shù)組的對(duì)象都有一個(gè)length屬性,因此還可以對(duì)這個(gè)屬性解構(gòu)賦值逆害。
let {length : len} = 'hello';
len // 5
Number和Boolean的解構(gòu)賦值
解構(gòu)賦值時(shí)头镊,如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對(duì)象魄幕。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
null和undefined的解構(gòu)賦值
由于undefined和null無法轉(zhuǎn)為對(duì)象相艇,所以對(duì)它們進(jìn)行解構(gòu)賦值,都會(huì)報(bào)錯(cuò)纯陨。
解構(gòu)賦值的用途
- 變量交換
let x = 1;
let y = 2;
[x, y] = [y, x];
- 取函數(shù)的返回值
// 返回一個(gè)數(shù)組
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一個(gè)對(duì)象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
- 提取JSON數(shù)據(jù)
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
- 函數(shù)參數(shù)的默認(rèn)值坛芽,不用再寫
var foo = config.foo || 'default foo'
;這樣的語句留储。
字符串的擴(kuò)展
includes、startsWith和endsWith
傳統(tǒng)上咙轩,JavaScript只有indexOf方法获讳,可以用來確定一個(gè)字符串是否包含在另一個(gè)字符串中。ES6又提供了三種新方法活喊。
- includes():返回布爾值丐膝,表示是否找到了參數(shù)字符串。
- startsWith():返回布爾值钾菊,表示參數(shù)字符串是否在源字符串的頭部帅矗。
- endsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的尾部煞烫。
var s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
這三個(gè)方法都支持第二個(gè)參數(shù)浑此,表示開始搜索的位置
var s = 'Hello world!';
s.startsWith('world', 6) // true红竭,第二個(gè)參數(shù)表示從索引n開始
s.endsWith('Hello', 5) // true,第二個(gè)參數(shù)表示前n個(gè)字符
s.includes('Hello', 6) // false赡若,第二個(gè)參數(shù)表示從索引n開始
fo-of循環(huán)
for-of循環(huán)的功能
- for-of循環(huán)可以用來遍歷數(shù)組,for-in循環(huán)用來遍歷對(duì)象屬性身腻。
for (var value of myArray) {
console.log(value);
}
- 這是最簡潔牛隅、最直接的遍歷數(shù)組元素的語法
- 這個(gè)方法避開了for-in循環(huán)的所有缺陷
- 與forEach()不同的是,它可以正確響應(yīng)break显设、continue和return語句
- for-of循環(huán)不僅支持?jǐn)?shù)組慷妙,還支持大多數(shù)類數(shù)組對(duì)象架馋,例如DOM NodeList對(duì)象姚淆。
- for-of循環(huán)也支持字符串遍歷,它將字符串視為一系列的Unicode字符來進(jìn)行遍歷:
for (var chr of "") {
alert(chr);
}
repeat方法
repeat(n) n
是一個(gè)數(shù)字妒蔚,表示將原字符串重復(fù)n次贞绵,返回一個(gè)新字符串
'x'.repeat(3) // "xxx"
參數(shù)如果是小數(shù)溯祸,會(huì)被取整,如果repeat的參數(shù)是負(fù)數(shù)或者Infinity,會(huì)報(bào)錯(cuò)舞肆。
'na'.repeat(2.9) // "nana"
如果參數(shù)是0到-1之間的小數(shù)焦辅,則等同于0,這是因?yàn)闀?huì)先進(jìn)行取整運(yùn)算椿胯。0到-1之間的小數(shù)筷登,取整以后等于-0,repeat視同為0哩盲。
'na'.repeat(-0.9) // ""
'na'.repeat(NaN) // ""
如果repeat的參數(shù)是字符串前方,則會(huì)先轉(zhuǎn)換成數(shù)字。
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
padStart()廉油,padEnd()
padStart()用于頭部補(bǔ)全惠险,padEnd()用于尾部補(bǔ)全绍刮。一共接受兩個(gè)參數(shù)纳寂,第一個(gè)參數(shù)用來指定字符串的最小長度辰如,第二個(gè)參數(shù)是用來補(bǔ)全的字符串译断。如果省略第二個(gè)參數(shù)非剃,默認(rèn)使用空格補(bǔ)全長度瞻颂。
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(4, 'ab') // 'xaba'
'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '
如果原字符串的長度霜威,等于或大于指定的最小長度泣栈,則返回原字符串。
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'
如果用來補(bǔ)全的字符串與原字符串抑进,兩者的長度之和超過了指定的最小長度强经,則會(huì)截去超出位數(shù)的補(bǔ)全字符串。
'abc'.padStart(10, '0123456789')// '0123456abc'
模板字符串
模板字符串(template string)是增強(qiáng)版的字符串寺渗,用反引號(hào)``
標(biāo)識(shí)匿情。它可以當(dāng)作普通字符串使用,也可以用來定義多行字符串户秤,或者在字符串中嵌入變量,模板字符串中嵌入變量码秉,需要將變量名寫在${}
之中。鸡号。
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
console.log(`string text line 1
string text line 2`);
// 字符串中嵌入變量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
關(guān)于模板字符串嵌入變量
- 大括號(hào)內(nèi)部可以放入任意的JavaScript表達(dá)式转砖,可以進(jìn)行運(yùn)算,以及引用對(duì)象屬性鲸伴。
var x = 1;
var y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"
var obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// 3
- 模板字符串之中還能調(diào)用函數(shù)府蔗。
function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar
如果大括號(hào)中的值不是字符串,將默認(rèn)調(diào)用toString方法轉(zhuǎn)換成字符串汞窗,如果模板字符串中的變量沒有聲明姓赤,將報(bào)錯(cuò)。
- 標(biāo)簽?zāi)0?br> 模板字符串可以緊跟在一個(gè)函數(shù)名后面仲吏,該函數(shù)將被調(diào)用來處理這個(gè)模板字符串不铆。這被稱為“標(biāo)簽?zāi)0濉惫δ埽╰agged template)。標(biāo)簽?zāi)0迤鋵?shí)不是模板裹唆,而是函數(shù)調(diào)用的一種特殊形式誓斥。“標(biāo)簽”指的就是函數(shù)许帐,緊跟在后面的模板字符串就是它的參數(shù)劳坑。
alert`123`
// 等同于
alert(123)
如果模板字符里面有變量,就不是簡單的調(diào)用了成畦,而是會(huì)將模板字符串先處理成多個(gè)參數(shù)距芬,再調(diào)用函數(shù)。
var a = 5;
var b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
tag函數(shù)的第一個(gè)參數(shù)是一個(gè)數(shù)組循帐,數(shù)組項(xiàng)是模板字符串中那些沒有變量替換的部分框仔,也就是說,變量替換只發(fā)生在數(shù)組各個(gè)項(xiàng)之間拄养。
tag函數(shù)的其他參數(shù)存和,都是模板字符串各個(gè)變量被替換后的值。由于本例中,模板字符串含有兩個(gè)變量捐腿,因此tag會(huì)接受到兩個(gè)參數(shù)。
tag函數(shù)所有參數(shù)的實(shí)際值如上面的代碼柿顶。
- String.raw函數(shù)
String.raw
方法茄袖,往往用來充當(dāng)模板字符串的處理函數(shù),返回一個(gè)斜杠都被轉(zhuǎn)義(即斜杠前面再加一個(gè)斜杠)的字符串嘁锯,對(duì)應(yīng)于替換變量后的模板字符串宪祥。如果原字符串的斜杠已經(jīng)轉(zhuǎn)義,那么String.raw不會(huì)做任何處理家乘。
String.raw`Hi\n${2+3}!`;
// "Hi\\n5!"
String.raw`Hi\u000A!`;
// 'Hi\\u000A!'
String.raw`Hi\\n`
// "Hi\\n"
正則表達(dá)式的擴(kuò)展
關(guān)于ES6中RegExp構(gòu)造函數(shù)
在ES6中RegExp構(gòu)造函數(shù)的第一個(gè)參數(shù)如果是一個(gè)正則表達(dá)式蝗羊,可以使用第二個(gè)參數(shù)指定正則的的修飾符,在ES5中不可以仁锯,返回的正則表達(dá)式會(huì)忽略原有的正則表達(dá)式的修飾符耀找,只使用新指定的修飾符。
new RegExp(/abc/ig, 'i')// /abc/i
關(guān)于字符串的正則方法
字符串對(duì)象共有4個(gè)方法业崖,可以使用正則表達(dá)式:match()野芒、replace()、search()和split()双炕。
新增u修飾符
ES6對(duì)正則表達(dá)式添加了u修飾符狞悲,含義為“Unicode模式”,用來正確處理大于\uFFFF的Unicode字符站超。也就是說,會(huì)正確處理四個(gè)字節(jié)的UTF-16編碼戚炫。
Number的擴(kuò)展
二進(jìn)制和八進(jìn)制的新的寫法
ES6 提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法媳纬,分別用前綴0b(或0B)和0o(或0O)表示缩赛。
**Number.isFinite(), Number.isNaN() **
ES6在Number對(duì)象上施无,新提供了Number.isFinite()和Number.isNaN()兩個(gè)方法狮含。
Number.isFinite()用來檢查一個(gè)數(shù)值是否為有限的(finite)。
Number.isNaN()用來檢查一個(gè)值是否為NaN初肉。
這兩個(gè)新方法只對(duì)數(shù)值有效,Number.isFinite()對(duì)于非數(shù)值一律返回false, Number.isNaN()只有對(duì)于NaN才返回true例嘱,非NaN一律返回false狡逢。
Number.parseInt(), Number.parseFloat()
ES6將全局方法parseInt()和parseFloat(),移植到Number對(duì)象上面拼卵,行為完全保持不變奢浑。
Number.isInteger()
Number.isInteger()用來判斷一個(gè)值是否為整數(shù)。
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
Number.isInteger("15") // false
Number.EPSILON
js中浮點(diǎn)數(shù)計(jì)算是不精確的(0.1+0.2)腋腮。ES6在Number對(duì)象上面雀彼,新增一個(gè)極小的常量Number.EPSILON,Number.EPSILON的實(shí)質(zhì)是一個(gè)可以接受的誤差范圍。為浮點(diǎn)數(shù)計(jì)算即寡,設(shè)置一個(gè)誤差范圍.如果這個(gè)誤差能夠小于Number.EPSILON徊哑,我們就可以認(rèn)為得到了正確結(jié)果。
安全整數(shù)和Number.isSafeInteger()
JavaScript能夠準(zhǔn)確表示的整數(shù)范圍在-2^53(-2的53次方)
到2^53(2的53次方)
之間(不含兩個(gè)端點(diǎn))聪富,超過這個(gè)范圍莺丑,無法精確表示這個(gè)值。
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER這兩個(gè)常量墩蔓,用來表示這個(gè)范圍的上下限梢莽。
Number.isSafeInteger()則是用來判斷一個(gè)整數(shù)是否落在這個(gè)范圍之內(nèi)。
Math對(duì)象的擴(kuò)展
ES6在Math對(duì)象上新增了17個(gè)與數(shù)學(xué)相關(guān)的方法钢拧。所有這些方法都是靜態(tài)方法蟹漓,只能在Math對(duì)象上調(diào)用。
-
Math.trunc
方法用于去除一個(gè)數(shù)的小數(shù)部分源内,返回整數(shù)部分葡粒。對(duì)于非數(shù)值份殿,Math.trunc內(nèi)部使用Number方法將其先轉(zhuǎn)為數(shù)值。對(duì)于空值和無法截取整數(shù)的值嗽交,返回NaN卿嘲。
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc('123.456')// 123
Math.trunc(NaN); // NaN
Math.trunc('foo'); // NaN
Math.trunc(); // NaN
-
Math.sign
方法用來判斷一個(gè)數(shù)到底是正數(shù)、負(fù)數(shù)夫壁、還是零拾枣。它會(huì)返回五種值。
參數(shù)為正數(shù)盒让,返回+1梅肤;
參數(shù)為負(fù)數(shù),返回-1邑茄;
參數(shù)為0姨蝴,返回0;
參數(shù)為-0肺缕,返回-0;
其他值左医,返回NaN。
-
Math.cbrt
方法用于計(jì)算一個(gè)數(shù)的立方根同木。對(duì)于非數(shù)值浮梢,Math.cbrt方法內(nèi)部也是先使用Number方法將其轉(zhuǎn)為數(shù)值。
Math.cbrt('8') // 2
Math.cbrt('hello') // NaN
Math.cbrt(1) // 1
Math.cbrt(2) // 1.2599210498948734
Math.clz32
方法返回一個(gè)數(shù)的32位無符號(hào)整數(shù)形式有多少個(gè)前導(dǎo)0彤路。Math.imul
方法返回兩個(gè)數(shù)以32位帶符號(hào)整數(shù)形式相乘的結(jié)果秕硝,返回的也是一個(gè)32位的帶符號(hào)整數(shù)。Math.fround
方法返回一個(gè)數(shù)的單精度浮點(diǎn)數(shù)形式斩萌。Math.hypot
方法返回所有參數(shù)的平方和的平方根缝裤。Math.expm1(x)
返回ex - 1,即Math.exp(x) - 1颊郎。ath.log1p(x)
方法返回1 + x的自然對(duì)數(shù)憋飞,即Math.log(1 + x)。如果x小于-1姆吭,返回NaN榛做。Math.log10(x)
返回以10為底的x的對(duì)數(shù)。如果x小于0内狸,則返回NaN检眯。Math.log2(x)
返回以2為底的x的對(duì)數(shù)。如果x小于0昆淡,則返回NaN锰瘸。Math.sinh(x)
返回x的雙曲正弦(hyperbolic sine)Math.cosh(x)
返回x的雙曲余弦(hyperbolic cosine)Math.tanh(x)
返回x的雙曲正切(hyperbolic tangent)Math.asinh(x)
返回x的反雙曲正弦(inverse hyperbolic sine)Math.acosh(x)
返回x的反雙曲余弦(inverse hyperbolic cosine)Math.atanh(x)
返回x的反雙曲正切(inverse hyperbolic tangent)Math.signbit()
方法判斷一個(gè)數(shù)的符號(hào)位是否設(shè)置了
如果參數(shù)是NaN,返回false
如果參數(shù)是-0昂灵,返回true
如果參數(shù)是負(fù)值避凝,返回true
其他情況返回falseES2016 新增了一個(gè)指數(shù)運(yùn)算符(**)舞萄。指數(shù)運(yùn)算符可以與等號(hào)結(jié)合,形成一個(gè)新的賦值運(yùn)算符(**=)管削。
2 ** 2 // 4
2 ** 3 // 8
a **= 2;// 等同于 a = a * a;
數(shù)組的擴(kuò)展
-
Array.from
方法用于將兩類對(duì)象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對(duì)象(array-like object)和可遍歷(iterable)的對(duì)象(包括ES6新增的數(shù)據(jù)結(jié)構(gòu)Set和Map)倒脓。只要是部署了Iterator接口的數(shù)據(jù)結(jié)構(gòu),Array.from都能將其轉(zhuǎn)為數(shù)組含思。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES6的寫法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
-
Array.of
方法用于將一組值崎弃,轉(zhuǎn)換為數(shù)組。如果沒有參數(shù)含潘,就返回一個(gè)空數(shù)組饲做。
Array.of(3, 11, 8) // [3,11,8]
- 數(shù)組實(shí)例的
copyWithin()
方法,將數(shù)組指定位置的成員復(fù)制到其他位置(會(huì)覆蓋原有成員)遏弱,然后返回當(dāng)前數(shù)組艇炎。也就是說,使用這個(gè)方法腾窝,會(huì)修改當(dāng)前數(shù)組。
它接受三個(gè)參數(shù)居砖。
target(必需):從該位置開始替換數(shù)據(jù)虹脯。
start(可選):從該位置開始讀取數(shù)據(jù),默認(rèn)為0奏候。如果為負(fù)值循集,表示倒數(shù)。
end(可選):到該位置前停止讀取數(shù)據(jù)蔗草,默認(rèn)等于數(shù)組長度咒彤。如果為負(fù)值,表示倒數(shù)咒精。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
- 數(shù)組實(shí)例的find()和findIndex()
數(shù)組實(shí)例的find方法镶柱,用于找出第一個(gè)
符合條件的數(shù)組成員。它的參數(shù)是一個(gè)回調(diào)函數(shù)模叙,所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù)歇拆,直到找出第一個(gè)返回值為true的成員,然后返回該成員范咨。如果沒有符合條件的成員故觅,則返回undefined。
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
上面代碼中渠啊,find方法的回調(diào)函數(shù)可以接受三個(gè)參數(shù)输吏,依次為當(dāng)前的值、當(dāng)前的位置和原數(shù)組替蛉。
數(shù)組實(shí)例的findIndex方法的用法與find方法非常類似贯溅,返回第一個(gè)符合條件的數(shù)組成員的位置拄氯,如果所有成員都不符合條件,則返回-1盗迟。
- fill方法使用給定值坤邪,填充一個(gè)數(shù)組。用于初始化空數(shù)組罚缕,第二個(gè)和第三個(gè)參數(shù)艇纺,用于指定填充的起始位置和結(jié)束位置。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
-
keys()
是對(duì)鍵名的遍歷,可以用for...of循環(huán)進(jìn)行遍歷 -
values()
是對(duì)鍵值的遍歷,可以用for...of循環(huán)進(jìn)行遍歷 -
entries()
是對(duì)鍵值對(duì)的遍歷,可以用for...of循環(huán)進(jìn)行遍歷 -
Array.prototype.includes
方法返回一個(gè)布爾值邮弹,表示某個(gè)數(shù)組是否包含給定的值黔衡,與字符串的includes方法類似。該方法屬于ES7腌乡,但Babel轉(zhuǎn)碼器已經(jīng)支持盟劫。
函數(shù)的擴(kuò)展
參數(shù)的默認(rèn)值
- 可以直接在函數(shù)的實(shí)參中設(shè)置函數(shù)的默認(rèn)值
function log(x, y = 'World') {
console.log(x, y);
}
- 參數(shù)變量是默認(rèn)聲明的,所以不能用let或const再次聲明与纽。
- 使用參數(shù)默認(rèn)值時(shí)侣签,函數(shù)不能有同名參數(shù)。
function foo(x, x, y = 1) {
// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context
- 通常情況下急迂,定義了默認(rèn)值的參數(shù)影所,應(yīng)該是函數(shù)的尾參數(shù)。因?yàn)檫@樣比較容易看出來僚碎,到底省略了哪些參數(shù)猴娩。如果非尾部的參數(shù)設(shè)置默認(rèn)值,實(shí)際上這個(gè)參數(shù)是沒法省略的勺阐。
- 指定了默認(rèn)值以后卷中,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個(gè)數(shù)渊抽。也就是說蟆豫,指定了默認(rèn)值后,length屬性將失真懒闷。rest參數(shù)(可變參數(shù))也不會(huì)計(jì)入length屬性无埃。
- 如果設(shè)置了默認(rèn)值的參數(shù)不是尾參數(shù),那么length屬性也不再計(jì)入后面的參數(shù)了毛雇。
- 把參數(shù)的默認(rèn)值設(shè)成undefined表明這個(gè)參數(shù)是可以省略的
作用域
一旦設(shè)置了參數(shù)的默認(rèn)值嫉称,函數(shù)執(zhí)行時(shí),參數(shù)會(huì)形成一個(gè)單獨(dú)的作用域灵疮。等到執(zhí)行完织阅,這個(gè)作用域就會(huì)消失。這種語法行為震捣,在不設(shè)置參數(shù)默認(rèn)值時(shí)荔棉,是不會(huì)出現(xiàn)的闹炉。
rest參數(shù)
ES6 引入 rest 參數(shù)(形式為“...變量名”),用于獲取函數(shù)的多余參數(shù)润樱,這樣就不需要使用arguments對(duì)象了渣触。rest 參數(shù)是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中壹若。rest 參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù))嗅钻,否則會(huì)報(bào)錯(cuò)。
擴(kuò)展運(yùn)算符
- 擴(kuò)展運(yùn)算符(spread)是三個(gè)點(diǎn)(...)店展。它好比 rest 參數(shù)的逆運(yùn)算养篓,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。
任何Iterator接口的對(duì)象赂蕴,都可以用擴(kuò)展運(yùn)算符轉(zhuǎn)為真正的數(shù)組柳弄。
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
該運(yùn)算符主要用于函數(shù)調(diào)用。
function add(x, y) {
return x + y;
}
var numbers = [4, 38];
add(...numbers) // 42
- 擴(kuò)展運(yùn)算符還可以將字符串轉(zhuǎn)為真正的數(shù)組概说。
[...'hello']
// [ "h", "e", "l", "l", "o" ]
- 函數(shù)的name屬性碧注,返回該函數(shù)的函數(shù)名。如果將一個(gè)具名函數(shù)賦值給一個(gè)變量糖赔,則 ES5 和 ES6 的name屬性都返回這個(gè)具名函數(shù)原本的名字应闯。
箭頭函數(shù)
- 基本用法
var f = () => 5;
var f = v => v;
var sum = (num1, num2) => num1 + num2;
- 如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號(hào)將它們括起來挂捻,并且使用return語句返回。
var sum = (num1, num2) => {
console.log(num1 + num2);
return num1 + num2;
}
- 由于大括號(hào)被解釋為代碼塊船万,所以如果箭頭函數(shù)直接返回一個(gè)對(duì)象刻撒,必須在對(duì)象外面加上括號(hào)
var getTempItem = id => ({ id: id, name: "Temp" });
箭頭函數(shù)的注意點(diǎn)
- 箭頭函數(shù)的this是他的父級(jí)的this,因?yàn)槭羌^函數(shù)根本沒有自己的this耿导,導(dǎo)致內(nèi)部的this就是外層代碼塊的this声怔。正是因?yàn)樗鼪]有this,所以也就不能用作構(gòu)造函數(shù)舱呻。
- 不可以當(dāng)作構(gòu)造函數(shù)醋火,也就是說,不可以使用new命令箱吕,否則會(huì)拋出一個(gè)錯(cuò)誤芥驳。
- 不可以使用arguments對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在茬高。如果要用兆旬,可以用Rest參數(shù)代替。
- 不可以使用yield命令怎栽,因此箭頭函數(shù)不能用作Generator函數(shù)丽猬。
- 箭頭函數(shù)不存在arguments宿饱、super、new.target這三個(gè)變量脚祟。
- 箭頭函數(shù)不能用call()谬以、apply()、bind()這些方法去改變this的指向由桌。
函數(shù)綁定運(yùn)算符(::)
這是一個(gè)ES7的提案为黎,但是babel已經(jīng)支持
雙冒號(hào)左邊是一個(gè)對(duì)象,右邊是一個(gè)函數(shù)沥寥。該運(yùn)算符會(huì)自動(dòng)將左邊的對(duì)象碍舍,作為上下文環(huán)境(即this對(duì)象),綁定到右邊的函數(shù)上面邑雅。
foo::bar;
// 等同于
bar.bind(foo);
var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;
對(duì)象的擴(kuò)展
屬性的簡潔寫法
ES6允許直接寫入變量和函數(shù)片橡,作為對(duì)象的屬性和方法。這樣的書寫更加簡潔,簡潔寫法的屬性名總是字符串淮野,這會(huì)導(dǎo)致一些看上去比較奇怪的結(jié)果捧书。
var obj = {
class () {}
};
// 等同于
var obj = {
'class': function() {}
};
var birth = '2000/01/01';
var Person = {
name: '張三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};
- ES6可以用下面這種方式定義對(duì)象
let propKey = 'foo';
let obj = {
[propKey]: true,
['a' + 'bc']: 123
};
對(duì)象新增的方法
-
bject.is
是用來比較兩個(gè)值是否嚴(yán)格相等,與嚴(yán)格比較運(yùn)算符(===)的行為基本一致骤星。不同之處只有兩個(gè):一是+0不等于-0经瓷,二是NaN等于自身。
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
- Object.assign方法用于對(duì)象的合并洞难,將源對(duì)象(source)的所有可枚舉屬性舆吮,復(fù)制到目標(biāo)對(duì)象(target)。第一個(gè)參數(shù)是目標(biāo)對(duì)象队贱,后面的參數(shù)都是源對(duì)象色冀。
如果目標(biāo)對(duì)象與源對(duì)象有同名屬性,或多個(gè)源對(duì)象有同名屬性柱嫌,則后面的屬性會(huì)覆蓋前面的屬性锋恬。
如果該參數(shù)不是對(duì)象,則會(huì)先轉(zhuǎn)成對(duì)象编丘,然后返回与学。如果只有一個(gè)參數(shù),Object.assign會(huì)直接返回該參數(shù)嘉抓。由于undefined和null無法轉(zhuǎn)成對(duì)象索守,所以如果它們作為參數(shù)并且是目標(biāo)對(duì)象(即第一個(gè)參數(shù)),就會(huì)報(bào)錯(cuò)抑片。
未完待續(xù)蕾盯。。。
Symbol數(shù)據(jù)類型
ES5的對(duì)象屬性名都是字符串级遭,這容易造成屬性名的沖突望拖。ES6引入了一種新的原始數(shù)據(jù)類型Symbol,表示獨(dú)一無二的值挫鸽。它是JavaScript語言的第八種數(shù)據(jù)類型说敏。
let s = Symbol();
typeof s// "symbol"
Symbol函數(shù)前不能使用new命令,否則會(huì)報(bào)錯(cuò)丢郊。這是因?yàn)樯傻腟ymbol是一個(gè)原始類型的值盔沫,不是對(duì)象。也就是說枫匾,由于Symbol值不是對(duì)象架诞,所以不能添加屬性「绍裕基本上谴忧,它是一種類似于字符串的數(shù)據(jù)類型。
- Symbol函數(shù)可以接受一個(gè)字符串作為參數(shù)角虫,表示對(duì)Symbol實(shí)例的描述沾谓,主要是為了在控制臺(tái)顯示,或者轉(zhuǎn)為字符串時(shí)戳鹅,比較容易區(qū)分均驶。
Symbol函數(shù)的參數(shù)只是表示對(duì)當(dāng)前 Symbol 值的描述,因此相同參數(shù)的Symbol函數(shù)的返回值是不相等的枫虏。
// 沒有參數(shù)的情況
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
// 有參數(shù)的情況
var s1 = Symbol('foo');
var s2 = Symbol('foo');
s1 === s2 // false
- 如果 Symbol 的參數(shù)是一個(gè)對(duì)象妇穴,就會(huì)調(diào)用該對(duì)象的toString方法,將其轉(zhuǎn)為字符串隶债,然后才生成一個(gè) Symbol 值腾它。
- Symbol值不能與其他類型的值進(jìn)行運(yùn)算,會(huì)報(bào)錯(cuò)燃异。
- Symbol值能轉(zhuǎn)換成字符串和布爾值,但是不能轉(zhuǎn)換成數(shù)字继蜡。
- Symbol值可以用作對(duì)象的屬性名回俐。Symbol值作為對(duì)象屬性名時(shí),不能用點(diǎn)運(yùn)算符稀并。
var mySymbol = Symbol();
var a = {};
a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!
- 在對(duì)象的內(nèi)部仅颇,使用Symbol值定義屬性時(shí),Symbol值必須放在方括號(hào)之中碘举。
let s = Symbol();
let obj = {
[s]: function (arg) { ... }
};
obj[s](123);
上面代碼中忘瓦,如果s不放在方括號(hào)中,該屬性的鍵名就是字符串s引颈,而不是s所代表的那個(gè)Symbol值
- Symbol值作為屬性名時(shí)耕皮,該屬性是公有屬性境蜕,不是私有屬性。
- Symbol作為屬性名不可以被遍歷凌停,可以使用Object.getOwnPropertySymbols方法獲得屬性名粱年。
Symbol相關(guān)方法
- Symbol.for()
Symbol.for接受一個(gè)字符串作為參數(shù),搜索有沒有以該參數(shù)作為名稱的Symbol值罚拟。如果有台诗,就返回這個(gè)Symbol值,否則就新建并返回一個(gè)以該字符串為名稱的Symbol值赐俗。Symbol.for會(huì)被登記在全局環(huán)境中供搜索
var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo');
s1 === s2 // true
- Symbol.keyFor() 方法返回一個(gè)已登記的 Symbol 類型值的key拉队。
就是前面已經(jīng)執(zhí)行過Symbol.for的
Symbol的內(nèi)置屬性
ES6提供了11個(gè)內(nèi)置的Symbol屬性,指向語言內(nèi)部使用的方法阻逮。
-
Symbol.hasInstance
屬性粱快,指向一個(gè)內(nèi)部方法。當(dāng)其他對(duì)象使用instanceof運(yùn)算符夺鲜,判斷是否為該對(duì)象的實(shí)例時(shí)皆尔,會(huì)調(diào)用這個(gè)方法。比如币励,foo instanceof Foo在語言內(nèi)部慷蠕,實(shí)際調(diào)用的是Foo[Symbol.hasInstance](foo)。 -
Symbol.isConcatSpreadable
屬性等于一個(gè)布爾值食呻,表示該對(duì)象使用Array.prototype.concat()時(shí)流炕,是否可以展開。 -
Symbol.species
屬性仅胞,指向當(dāng)前對(duì)象的構(gòu)造函數(shù)每辟。創(chuàng)造實(shí)例時(shí),默認(rèn)會(huì)調(diào)用這個(gè)方法干旧,即使用這個(gè)屬性返回的函數(shù)當(dāng)作構(gòu)造函數(shù)渠欺,來創(chuàng)造新的實(shí)例對(duì)象 -
Symbol.match
屬性,指向一個(gè)函數(shù)椎眯。當(dāng)執(zhí)行str.match(myObject)時(shí)挠将,如果該屬性存在,會(huì)調(diào)用它编整,返回該方法的返回值舔稀。 -
Symbol.replace
屬性,指向一個(gè)方法掌测,當(dāng)該對(duì)象被String.prototype.replace方法調(diào)用時(shí)内贮,會(huì)返回該方法的返回值。Symbol.replace方法會(huì)收到兩個(gè)參數(shù),第一個(gè)參數(shù)是replace方法正在作用的對(duì)象夜郁,第二個(gè)參數(shù)是替換后的值 -
Symbol.search
屬性什燕,指向一個(gè)方法,當(dāng)該對(duì)象被String.prototype.search方法調(diào)用時(shí)拂酣,會(huì)返回該方法的返回值秋冰。 -
Symbol.split
屬性,指向一個(gè)方法婶熬,當(dāng)該對(duì)象被String.prototype.split方法調(diào)用時(shí)剑勾,會(huì)返回該方法的返回值。 -
Symbol.iterator
屬性赵颅,指向該對(duì)象的默認(rèn)遍歷器方法虽另。 -
Symbol.toPrimitive
屬性,指向一個(gè)方法饺谬。該對(duì)象被轉(zhuǎn)為原始類型的值時(shí)捂刺,會(huì)調(diào)用這個(gè)方法,返回該對(duì)象對(duì)應(yīng)的原始類型值募寨。 -
Symbol.toStringTag
屬性族展,指向一個(gè)方法。在該對(duì)象上面調(diào)用Object.prototype.toString方法時(shí)拔鹰,如果這個(gè)屬性存在仪缸,它的返回值會(huì)出現(xiàn)在toString方法返回的字符串之中,表示對(duì)象的類型列肢。也就是說恰画,這個(gè)屬性可以用來定制[object Object]或[object Array]中object后面的那個(gè)字符串。 -
Symbol.unscopables
屬性瓷马,指向一個(gè)對(duì)象拴还。該對(duì)象指定了使用with關(guān)鍵字時(shí),哪些屬性會(huì)被with環(huán)境排除欧聘。
Set和Map數(shù)據(jù)結(jié)構(gòu)
Set
ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set片林。它類似于數(shù)組,但是成員的值都是唯一的怀骤,沒有重復(fù)的值费封。
數(shù)組去重的新增2種寫法
// 數(shù)組去重
[...new Set(array)]
//數(shù)組去重
function dedupe(array) {
return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]) // [1, 2, 3]
Set相關(guān)的方法
- Set.prototype.constructor:構(gòu)造函數(shù),默認(rèn)就是Set函數(shù)晒喷。
- Set.prototype.size:返回Set實(shí)例的成員總數(shù)孝偎。
增刪改查
- add(value):添加某個(gè)值访敌,返回Set結(jié)構(gòu)本身凉敲。
- delete(value):刪除某個(gè)值,返回一個(gè)布爾值,表示刪除是否成功爷抓。
- has(value):返回一個(gè)布爾值势决,表示該值是否為Set的成員。
- clear():清除所有成員蓝撇,沒有返回值。
遍歷
- keys():返回鍵名的遍歷器
- values():返回鍵值的遍歷器
- entries():返回鍵值對(duì)的遍歷器
- forEach():使用回調(diào)函數(shù)遍歷每個(gè)成員
WeakSet
WeakSet結(jié)構(gòu)與Set類似,也是不重復(fù)的值的集合汗捡。但是澈驼,它與Set有兩個(gè)區(qū)別。
- WeakSet的成員只能是對(duì)象独柑,而不能是其他類型的值迈窟。
- WeakSet中的對(duì)象都是弱引用,即垃圾回收機(jī)制不考慮WeakSet對(duì)該對(duì)象的引用忌栅,也就是說车酣,如果其他對(duì)象都不再引用該對(duì)象,那么垃圾回收機(jī)制會(huì)自動(dòng)回收該對(duì)象所占用的內(nèi)存索绪,不考慮該對(duì)象還存在于WeakSet之中湖员。這個(gè)特點(diǎn)意味著,無法引用WeakSet的成員瑞驱,因此WeakSet是不可遍歷的娘摔。
WeakSet相關(guān)方法
- WeakSet.prototype.add(value):向WeakSet實(shí)例添加一個(gè)新成員。
- WeakSet.prototype.delete(value):清除WeakSet實(shí)例的指定成員钱烟。
- WeakSet.prototype.has(value):返回一個(gè)布爾值晰筛,表示某個(gè)值是否在WeakSet實(shí)例之中。
Map
Map數(shù)據(jù)結(jié)構(gòu)類似于對(duì)象拴袭,也是鍵值對(duì)的集合读第,但是“鍵”的范圍不限于字符串,各種類型的值(包括對(duì)象)都可以當(dāng)作鍵拥刻。也就是說怜瞒,Object結(jié)構(gòu)提供了“字符串—值”的對(duì)應(yīng),Map結(jié)構(gòu)提供了“值—值”的對(duì)應(yīng)般哼,是一種更完善的Hash結(jié)構(gòu)實(shí)現(xiàn)吴汪。如果你需要“鍵值對(duì)”的數(shù)據(jù)結(jié)構(gòu),Map比Object更合適蒸眠。
只有對(duì)同一個(gè)對(duì)象的引用漾橙,Map結(jié)構(gòu)才將其視為同一個(gè)鍵。這一點(diǎn)要非常小心楞卡。
var map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
上面代碼的set和get方法霜运,表面是針對(duì)同一個(gè)鍵脾歇,但實(shí)際上這是兩個(gè)值,內(nèi)存地址是不一樣的淘捡,因此get方法無法讀取該鍵藕各,返回undefined。
Map相關(guān)屬性和方法
-
size
屬性返回Map結(jié)構(gòu)的成員總數(shù)焦除。 -
set
方法設(shè)置key所對(duì)應(yīng)的鍵值激况,然后返回整個(gè)Map結(jié)構(gòu)。如果key已經(jīng)有值膘魄,則鍵值會(huì)被更新乌逐,否則就新生成該鍵〈雌希可以采用鏈?zhǔn)綄懛ā?/li> -
get
方法讀取key對(duì)應(yīng)的鍵值黔帕,如果找不到key,返回undefined蹈丸。 -
has
方法返回一個(gè)布爾值成黄,表示某個(gè)鍵是否在Map數(shù)據(jù)結(jié)構(gòu)中。 -
delete
方法刪除某個(gè)鍵逻杖,返回true奋岁。如果刪除失敗,返回false荸百。 -
clear
方法清除所有成員闻伶,沒有返回值。 -
keys()
返回鍵名的遍歷器够话。 -
values()
返回鍵值的遍歷器蓝翰。 -
entries()
返回所有成員的遍歷器。 -
forEach()
遍歷Map的所有成員女嘲。
Map與其他數(shù)據(jù)類型的轉(zhuǎn)換
- Map轉(zhuǎn)為數(shù)組
Map轉(zhuǎn)為數(shù)組最方便的方法畜份,就是使用擴(kuò)展運(yùn)算符(...)。
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
- 數(shù)組轉(zhuǎn)為Map
將數(shù)組轉(zhuǎn)入Map構(gòu)造函數(shù)欣尼,就可以轉(zhuǎn)為Map爆雹。
new Map([[true, 7], [{foo: 3}, ['abc']]])
// Map {true => 7, Object {foo: 3} => ['abc']}
- Map轉(zhuǎn)為對(duì)象
如果所有Map的鍵都是字符串,它可以轉(zhuǎn)為對(duì)象愕鼓。
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
- 對(duì)象轉(zhuǎn)為Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// [ [ 'yes', true ], [ 'no', false ] ]
- Map轉(zhuǎn)為JSON
Map轉(zhuǎn)為JSON要區(qū)分兩種情況钙态。一種情況是,Map的鍵名都是字符串菇晃,這時(shí)可以選擇轉(zhuǎn)為對(duì)象JSON册倒。
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
另一種情況是,Map的鍵名有非字符串磺送,這時(shí)可以選擇轉(zhuǎn)為數(shù)組JSON驻子。
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
- JSON轉(zhuǎn)為Map
JSON轉(zhuǎn)為Map屈尼,正常情況下,所有鍵名都是字符串拴孤。
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes":true,"no":false}')
// Map {'yes' => true, 'no' => false}
有一種特殊情況,整個(gè)JSON就是一個(gè)數(shù)組甲捏,且每個(gè)數(shù)組成員本身演熟,又是一個(gè)有兩個(gè)成員的數(shù)組。這時(shí)司顿,它可以一一對(duì)應(yīng)地轉(zhuǎn)為Map芒粹。這往往是數(shù)組轉(zhuǎn)為JSON的逆操作大溜。
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}
WeakMap
WeakMap結(jié)構(gòu)與Map結(jié)構(gòu)基本類似钦奋,唯一的區(qū)別是它只接受對(duì)象作為鍵名(null除外),不接受其他類型的值作為鍵名付材,而且鍵名所指向的對(duì)象,不計(jì)入垃圾回收機(jī)制。
WeakMap只有四個(gè)方法可用:get()贰锁、set()压鉴、has()蟹腾、delete()叶洞。
Proxy
待續(xù)……
Reflect
待續(xù)……
Promise 對(duì)象
Promise 的含義
Promise 是異步編程的一種解決方案仅财,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大狈究。ES6將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法盏求,原生提供了Promise對(duì)象抖锥。
Promise亿眠,簡單說就是一個(gè)容器,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果磅废。從語法上說纳像,Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息拯勉。Promise 提供統(tǒng)一的 API竟趾,各種異步操作都可以用同樣的方法進(jìn)行處理。
Promise對(duì)象的特點(diǎn)
- 對(duì)象的狀態(tài)不受外界影響谜喊。Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài):Pending(進(jìn)行中)倦始、Resolved(已完成斗遏,又稱 Fulfilled)和Rejected(已失敗)鞋邑。只有異步操作的結(jié)果诵次,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個(gè)狀態(tài)枚碗。
- 一旦狀態(tài)改變逾一,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果肮雨。Promise對(duì)象的狀態(tài)改變遵堵,只有兩種可能:從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected。只要這兩種情況發(fā)生怨规,狀態(tài)就凝固了陌宿,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果波丰。如果改變已經(jīng)發(fā)生了壳坪,你再對(duì)Promise對(duì)象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果掰烟。這與事件(Event)完全不同爽蝴,事件的特點(diǎn)是,如果你錯(cuò)過了它纫骑,再去監(jiān)聽蝎亚,是得不到結(jié)果的。
Promise的缺點(diǎn)
- 無法取消Promise先馆,一旦新建它就會(huì)立即執(zhí)行颖对,無法中途取消
- 如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤磨隘,不會(huì)反應(yīng)到外部
- 當(dāng)處于Pending狀態(tài)時(shí)缤底,無法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)顾患。
Promise的基本用法
Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolve
和reject
个唧,它們是兩個(gè)函數(shù)江解。
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
-
resolve
的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸腜ending變?yōu)镽esolved)徙歼,在異步操作成功時(shí)調(diào)用犁河,并將異步操作的結(jié)果,作為參數(shù)傳遞出去魄梯; -
reject
的作用是桨螺,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸腜ending變?yōu)镽ejected),在異步操作失敗時(shí)調(diào)用酿秸,并將異步操作報(bào)出的錯(cuò)誤灭翔,作為參數(shù)傳遞出去。
Promise相關(guān)方法
-
then
方法可以分別指定當(dāng)promise的狀態(tài)是成功和失敗的時(shí)候的回調(diào)函數(shù)辣苏。then方法返回的是一個(gè)新的Promise實(shí)例(注意肝箱,不是原來那個(gè)Promise實(shí)例)。因此可以采用鏈?zhǔn)綄懛?/li>
promise.then(function(value) {
// 狀態(tài)成功的時(shí)候執(zhí)行的函數(shù)
}, function(error) {
// 狀態(tài)為失敗的時(shí)候執(zhí)行的函數(shù)稀蟋,這個(gè)函數(shù)可以省略
});
-
catch
相當(dāng)于.then(null, rejection)煌张,相當(dāng)于then方法的第二個(gè)參數(shù),一般用catch方法處理錯(cuò)誤退客,不用then方法骏融。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 處理 getJSON 和 前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤
console.log('發(fā)生錯(cuò)誤!', error);
});
-
Promise.all
方法用于將多個(gè)Promise實(shí)例萌狂,包裝成一個(gè)新的Promise實(shí)例绎谦。
var p = Promise.all([p1, p2, p3]);
- 只有p1、p2粥脚、p3的狀態(tài)都變成fulfilled窃肠,p的狀態(tài)才會(huì)變成fulfilled,此時(shí)p1刷允、p2冤留、p3的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)树灶。
- 只要p1纤怒、p2、p3之中有一個(gè)被rejected天通,p的狀態(tài)就變成rejected泊窘,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。
-
Promise.race
方法同樣是將多個(gè)Promise實(shí)例烘豹,包裝成一個(gè)新的Promise實(shí)例,只要p1瓜贾、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài)携悯,p的狀態(tài)就跟著改變祭芦。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給p的回調(diào)函數(shù)憔鬼。
ES6的構(gòu)造函數(shù)和繼承
通過class來創(chuàng)建一個(gè)類龟劲,構(gòu)造函數(shù)寫在constructor里面
創(chuàng)建父類
class 類名{
constructor(param1,param2){
//私有的屬性和方法
}
getName(){
//公有的屬性和方法
}
static getAge(){
//類的靜態(tài)方法,也就是類的私有方法轴或,實(shí)例不能使用
}
}
創(chuàng)建子類并繼承
class S extend F{
constructor(name,age,color){
super(name,age)//這句話必須要寫昌跌,寫了就是把父類的私有公有都繼承了過來
this.color=color//這樣給子類添加私有的
}
getSex(){
//這是子類公有的
}
}
Module的介紹
語法
// ES6模塊
import { stat, exists, readFile } from 'fs';
上面代碼的實(shí)質(zhì)是從fs模塊加載3個(gè)方法,其他方法不加載照雁。
嚴(yán)格模式
ES6 的模塊自動(dòng)采用嚴(yán)格模式蚕愤,不管你有沒有在模塊頭部加上"use strict";。
ES6 模塊之中囊榜,頂層的this指向undefined审胸,即不應(yīng)該在頂層代碼使用this亥宿。
模塊命令
模塊功能主要由兩個(gè)命令構(gòu)成:export和import卸勺。export命令用于規(guī)定模塊的對(duì)外接口,import命令用于輸入其他模塊提供的功能烫扼。import和export命令只能在模塊的頂層曙求,不能在代碼塊之中,類似于全局作用域
export命令
export命令用于將模塊內(nèi)部的變量輸出到外面。
寫法
// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
優(yōu)先采用下面這種寫法,export命令后面跟一個(gè)對(duì)象映企,對(duì)象里面是變量名
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
export輸出的變量就是本來的名字悟狱,但是可以使用as關(guān)鍵字重命名。
function v1() { ... }
export {
v1 as streamV1
};
ES6中不輸出任何接口的寫法
export {};//這個(gè)命令并不是輸出一個(gè)空對(duì)象堰氓,而是不輸出任何接口的 ES6 標(biāo)準(zhǔn)寫法挤渐。
import命令
import命令用于加載模塊
用法
import后面跟大括號(hào),里面指定要從其他模塊導(dǎo)入的變量名双絮。大括號(hào)里面的變量名浴麻,必須與被導(dǎo)入模塊對(duì)外接口的名稱相同。from
后面跟模塊的路徑囤攀,可以省略.js软免,如果不跟路徑,只寫模塊名焚挠,那么就必須要有配置文件來指定路徑
import {firstName, lastName, year} from './profile';
import命令也可以用as關(guān)鍵字重命名加載的變量;
import命令具有提升效果
膏萧,會(huì)提升到整個(gè)模塊的頭部,首先執(zhí)行。
import命令會(huì)執(zhí)行所加載的模塊榛泛;
import 'lodash';//只是執(zhí)行了模塊
整體加載模塊使用*
import * as circle from './circle';
export default 命令
export default 命令命令是默認(rèn)輸出的變量或函數(shù)蝌蹂,當(dāng)其他模塊加載該模塊時(shí),import命令可以為該匿名函數(shù)指定任意名字挟鸠。注意叉信,這時(shí)import命令后面,不使用大括號(hào)艘希。
export 與 import 的復(fù)合寫法
如果在一個(gè)模塊之中硼身,先輸入后輸出同一個(gè)模塊,import語句可以與export語句寫在一起覆享。
export { foo, bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';
export { foo, bar };
import函數(shù)
import函數(shù)是動(dòng)態(tài)加載模塊佳遂,類似于node的require,區(qū)別主要是前者是異步加載撒顿,后者是同步加載丑罪。
import()返回一個(gè) Promise 對(duì)象。后面可以跟then或catch方法
Module的加載實(shí)現(xiàn)
腳本的異步加載
在<script>標(biāo)簽中添加defer或async屬性凤壁,腳本就會(huì)異步加載吩屹。
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
defer與async的區(qū)別
是:前者要等到整個(gè)頁面正常渲染結(jié)束,才會(huì)執(zhí)行拧抖;后者一旦下載完煤搜,渲染引擎就會(huì)中斷渲染,執(zhí)行這個(gè)腳本以后唧席,再繼續(xù)渲染擦盾。一句話,defer是“渲染完再執(zhí)行”淌哟,async是“下載完就執(zhí)行”迹卢。另外,如果有多個(gè)defer腳本徒仓,會(huì)按照它們?cè)陧撁娉霈F(xiàn)的順序加載腐碱,而多個(gè)async腳本是不能保證加載順序的。
ES6的編程規(guī)則
let和const之間應(yīng)該優(yōu)先使用const掉弛,所有的函數(shù)都應(yīng)該設(shè)置為常量
靜態(tài)字符串一律使用單引號(hào)或反引號(hào)症见,不使用雙引號(hào)。動(dòng)態(tài)字符串使用反引號(hào)狰晚。
使用數(shù)組成員對(duì)變量賦值時(shí)筒饰,優(yōu)先使用解構(gòu)賦值。
函數(shù)的參數(shù)如果是對(duì)象的成員壁晒,優(yōu)先使用解構(gòu)賦值瓷们。
如果函數(shù)返回多個(gè)值,優(yōu)先使用對(duì)象的解構(gòu)賦值,而不是數(shù)組的解構(gòu)賦值谬晕。這樣便于以后添加返回值碘裕,以及更改返回值的順序。
單行定義的對(duì)象攒钳,最后一個(gè)成員不以逗號(hào)結(jié)尾帮孔。多行定義的對(duì)象,最后一個(gè)成員以逗號(hào)結(jié)尾不撑。
// bad
const a = { k1: v1, k2: v2, };
const b = {
k1: v1,
k2: v2
};
// good
const a = { k1: v1, k2: v2 };
const b = {
k1: v1,
k2: v2,
};
對(duì)象盡量靜態(tài)化文兢,一旦定義,就不得隨意添加新的屬性焕檬。如果添加屬性不可避免姆坚,要使用Object.assign方法。
對(duì)象的屬性和方法实愚,盡量采用簡潔表達(dá)法兼呵,這樣易于描述和書寫。
var ref = 'some value';
// good
const atom = {
ref,
value: 1,
addValue(value) {
return atom.value + value;
},
};
使用擴(kuò)展運(yùn)算符(...)拷貝數(shù)組腊敲。
使用Array.from方法击喂,將類似數(shù)組的對(duì)象轉(zhuǎn)為數(shù)組。
立即執(zhí)行函數(shù)可以寫成箭頭函數(shù)的形式碰辅。
(() => {
console.log('Welcome to the Internet.');
})();
那些需要使用函數(shù)表達(dá)式的場(chǎng)合懂昂,盡量用箭頭函數(shù)代替。因?yàn)檫@樣更簡潔乎赴,而且綁定了this忍法。
簡單的潮尝、單行的榕吼、不會(huì)復(fù)用的函數(shù),建議采用箭頭函數(shù)勉失。如果函數(shù)體較為復(fù)雜羹蚣,行數(shù)較多,還是應(yīng)該采用傳統(tǒng)的函數(shù)寫法乱凿。
所有配置項(xiàng)都應(yīng)該集中在一個(gè)對(duì)象顽素,放在最后一個(gè)參數(shù),布爾值不可以直接作為參數(shù)徒蟆。
使用rest運(yùn)算符(...)代替arguments胁出。因?yàn)閞est運(yùn)算符顯式表明你想要獲取參數(shù),而且arguments是一個(gè)類似數(shù)組的對(duì)象段审,而rest運(yùn)算符可以提供一個(gè)真正的數(shù)組全蝶。
使用默認(rèn)值語法設(shè)置函數(shù)參數(shù)的默認(rèn)值。
注意區(qū)分Object和Map,只有模擬現(xiàn)實(shí)世界的實(shí)體對(duì)象時(shí)抑淫,才使用Object绷落。如果只是需要key: value的數(shù)據(jù)結(jié)構(gòu),使用Map結(jié)構(gòu)始苇。因?yàn)镸ap有內(nèi)建的遍歷機(jī)制砌烁。
用Class,取代需要prototype的操作催式。因?yàn)镃lass的寫法更簡潔函喉,更易于理解。
使用extends實(shí)現(xiàn)繼承荣月,因?yàn)檫@樣更簡單函似,不會(huì)有破壞instanceof運(yùn)算的危險(xiǎn)。
Module語法是JavaScript模塊的標(biāo)準(zhǔn)寫法喉童,堅(jiān)持使用Module語法撇寞。使用import取代require。
使用export取代module.exports堂氯。
如果模塊只有一個(gè)輸出值蔑担,就使用export default,如果模塊有多個(gè)輸出值咽白,就不使用export default啤握,不要export default與普通的export同時(shí)使用。
不要在模塊輸入中使用通配符晶框。因?yàn)檫@樣可以確保你的模塊之中排抬,有一個(gè)默認(rèn)輸出(export default)。
如果模塊默認(rèn)輸出一個(gè)函數(shù)授段,函數(shù)名的首字母應(yīng)該小寫蹲蒲。
如果模塊默認(rèn)輸出一個(gè)對(duì)象,對(duì)象名的首字母應(yīng)該大寫侵贵。
-
使用ESLint檢查語法規(guī)則和代碼風(fēng)格届搁,保證寫出語法正確、風(fēng)格統(tǒng)一的代碼窍育。
[ESLint的使用方式](http://es6.ruanyifeng.com/#docs/style)