Bable的Es6 2 Es5工具
let與const
let
let
聲明的變量只在它所在的代碼塊有效。
{
let a = 10;
var b = 1;
}
a //Uncaught ReferenceError: a is not defined
b //1
let
聲明的i只在for
循環(huán)中有效
// let
for(let i=0;i<3;i++){} //let聲明的i只在for循環(huán)中有效
console.log(i); // ReferenceError: a is not defined
// var
for(var i=0;i<3;i++){} //for循環(huán)中的i是全局變量
console.log(i); //3 變量i只用來(lái)控制循環(huán)昔搂,但是循環(huán)結(jié)束后句惯,它并沒(méi)有消失土辩,泄露成了全局變量。
// let
let a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
// var
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i); //i是全局變量
};
}
a[6](); // 10
// 改進(jìn)版 var
var a = [];
for (var i = 0; i < 10; i++) {
(function(j) { //用一個(gè)閉包把里面的i與
a[j] = function () {
console.log(j)
}
})(i) //每一次循環(huán)的i其實(shí)都是一個(gè)新的變量
}
a[6]();
for
循環(huán)還特別之處抢野,設(shè)置循環(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
let
不存在變量提升
//let
console.log(bar); // 報(bào)錯(cuò)ReferenceError
let bar = 2;
//var
console.log(foo); // 輸出undefined
var foo = 2;
// var相當(dāng)于
var foo; //變量聲明默認(rèn)值為undefined
console.log(foo); // 輸出undefined
foo = 2; //先聲明再調(diào)用
“暫時(shí)性死區(qū)”(temporal dead zone指孤,簡(jiǎn)稱(chēng) TDZ)
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
let
不允許在相同作用域內(nèi)启涯,重復(fù)聲明同一個(gè)變量
let
實(shí)際上為 JavaScript 新增了塊級(jí)作用域
ES5 只有全局作用域和函數(shù)作用域,沒(méi)有塊級(jí)作用域
// let
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5 外層代碼塊不受內(nèi)層代碼塊的影響
}
// var 10
// IIFE 寫(xiě)法
(function () {
var tmp = ...;
...
}());
// 塊級(jí)作用域?qū)懛?{
let tmp = ...;
...
}
ES5 規(guī)定恃轩,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明逝嚎,不能在塊級(jí)作用域聲明
應(yīng)該避免在塊級(jí)作用域內(nèi)聲明函數(shù)
const
const
聲明一個(gè)只讀的常量
常量的值就不能改變
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
const
一旦聲明變量,就必須立即初始化,只聲明不賦值详恼,就會(huì)報(bào)錯(cuò)补君。
const
的作用域與let
命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。
const
命令聲明的常量也不存在提升
const
同樣存在暫時(shí)性死區(qū)
const
只能在聲明后使用
const
不可重復(fù)聲明
const
實(shí)際上保證的昧互,并不是變量的值不得改動(dòng)挽铁,而是變量指向的那個(gè)內(nèi)存地址不得改動(dòng)。
變量的解構(gòu)賦值
數(shù)組解構(gòu)賦值
如果解構(gòu)不成功敞掘,變量的值就等于undefined
解構(gòu)賦值允許指定默認(rèn)值
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è)位置是否有值。所以玖雁,只有當(dāng)一個(gè)數(shù)組成員嚴(yán)格等于undefined更扁,默認(rèn)值才會(huì)生效
默認(rèn)值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
對(duì)象解構(gòu)賦值
數(shù)組的元素是按次序排列的赫冬,變量的取值由它的位置決定浓镜;而對(duì)象的屬性沒(méi)有次序,變量必須與屬性同名劲厌,才能取到正確的值
如果變量名
與屬性名
不一致
let { foo} = { foo: 'aaa', bar: 'bbb' };
foo// "aaa"
let { foo:foo} = { foo: 'aaa', bar: 'bbb' };
foo// "aaa"
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
對(duì)象的解構(gòu)也可以指定默認(rèn)值
默認(rèn)值生效的條件是膛薛,對(duì)象的屬性值嚴(yán)格等于undefined
如果解構(gòu)失敗,變量的值等于undefined
如果要將一個(gè)已經(jīng)聲明的變量用于解構(gòu)賦值,會(huì)報(bào)錯(cuò)补鼻,因?yàn)?JavaScript 引擎會(huì)將{x}理解成一個(gè)代碼塊
// 錯(cuò)誤的寫(xiě)法
let x;
{x} = {x: 1}; // SyntaxError: syntax error
// 正確的寫(xiě)法
let x;
({x} = {x: 1});
字符串解構(gòu)賦值
數(shù)值和布爾值解構(gòu)賦值
函數(shù)的參數(shù)解構(gòu)賦值
函數(shù)參數(shù)的解構(gòu)也可以使用默認(rèn)值
字符串的擴(kuò)展
字符的 Unicode
charCodeAt()
能夠正確處理 4 個(gè)字節(jié)儲(chǔ)存的字符哄啄,返回一個(gè)字符的碼點(diǎn)雅任。
String.fromCodePoint()
字符串的遍歷
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
at()
normalize()
includes(),startsWith(),endsWith()
includes():返回布爾值,表示是否找到了參數(shù)字符串咨跌。
startsWith():返回布爾值沪么,表示參數(shù)字符串是否在原字符串的頭部。
endsWith():返回布爾值锌半,表示參數(shù)字符串是否在原字符串的尾部
repeat()
repeat方法返回一個(gè)新字符串成玫,表示將原字符串重復(fù)n次
padStart(),padEnd()
padStart()用于頭部補(bǔ)全,padEnd()用于尾部補(bǔ)全
模板字符串
模板字符串(template string)是增強(qiáng)版的字符串拳喻,用反引號(hào)(`)標(biāo)識(shí)
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
console.log(`string text line 1
string text line 2`);
// 字符串中嵌入變量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
使用模板字符串表示多行字符串,所有的空格和縮進(jìn)都會(huì)被保留在輸出之中,如果你不想要這個(gè)換行猪腕,可以使用trim方法消除它
標(biāo)簽?zāi)0?/h3>
String.raw()
正則的擴(kuò)展
數(shù)值的擴(kuò)展
二進(jìn)制和八進(jìn)制
Number.isFinite(),Number.isNaN()
只對(duì)數(shù)值有效
Number.parseInt(),Number.parseFloat()
Number.isInteger()
Number.isInteger()用來(lái)判斷一個(gè)數(shù)值是否為整數(shù)
由于 JavaScript 采用 IEEE 754 標(biāo)準(zhǔn)冗澈,數(shù)值存儲(chǔ)為64位雙精度格式,數(shù)值精度最多可以達(dá)到 53 個(gè)二進(jìn)制位(1 個(gè)隱藏位與 52 個(gè)有效位)陋葡。如果數(shù)值的精度超過(guò)這個(gè)限度亚亲,第54位及后面的位就會(huì)被丟棄,這種情況下腐缤,Number.isInteger可能會(huì)誤判捌归。
Number.EPSILON
極小的常量Number.EPSILON。根據(jù)規(guī)格岭粤,它表示 1 與大于 1 的最小浮點(diǎn)數(shù)之間的差
Number.EPSILON === Math.pow(2, -52)
0.1 + 0.2 === 0.3 // false
Number.isSafeInteger()
JavaScript 能夠準(zhǔn)確表示的整數(shù)范圍在-253到253之間(不含兩個(gè)端點(diǎn))惜索,超過(guò)這個(gè)范圍,無(wú)法精確表示這個(gè)值,Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER這兩個(gè)常量剃浇,用來(lái)表示這個(gè)范圍的上下限,Number.isSafeInteger()則是用來(lái)判斷一個(gè)整數(shù)是否落在這個(gè)范圍之內(nèi)
Math.trunc()
Math.trunc方法用于去除一個(gè)數(shù)的小數(shù)部分巾兆,返回整數(shù)部分
Math.sign()
Math.sign方法用來(lái)判斷一個(gè)數(shù)到底是正數(shù)、負(fù)數(shù)虎囚、還是零角塑。對(duì)于非數(shù)值,會(huì)先將其轉(zhuǎn)換為數(shù)值
Math.cbrt()
Math.cbrt方法用于計(jì)算一個(gè)數(shù)的立方根
指數(shù)運(yùn)算符(**)
2**2 //4
a **= 2; // 等同于 a = a * a;
函數(shù)的擴(kuò)展
ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值淘讥,即直接寫(xiě)在參數(shù)定義的后面
function log(x, y = 'World') {
console.log(x, y);
}
參數(shù)變量是默認(rèn)聲明的圃伶,所以不能用let或const再次聲明
使用參數(shù)默認(rèn)值時(shí),函數(shù)不能有同名參數(shù)
參數(shù)默認(rèn)值不是傳值的蒲列,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值窒朋。也就是說(shuō),參數(shù)默認(rèn)值是惰性求值的
定義了默認(rèn)值的參數(shù)蝗岖,應(yīng)該是函數(shù)的尾參數(shù)
如果傳入undefined炼邀,將觸發(fā)該參數(shù)等于默認(rèn)值,null則沒(méi)有這個(gè)效果
函數(shù)的length屬性
函數(shù)的length屬性剪侮,將返回沒(méi)有指定默認(rèn)值的參數(shù)個(gè)數(shù)拭宁。也就是說(shuō)洛退,指定了默認(rèn)值后,length屬性將失真
因?yàn)閘ength屬性的含義是杰标,該函數(shù)預(yù)期傳入的參數(shù)個(gè)數(shù)兵怯。
作用域
參數(shù)會(huì)形成一個(gè)單獨(dú)的作用域(context)。等到初始化結(jié)束腔剂,這個(gè)作用域就會(huì)消失媒区。這種語(yǔ)法行為,在不設(shè)置參數(shù)默認(rèn)值時(shí)掸犬,是不會(huì)出現(xiàn)的
參數(shù)默認(rèn)值設(shè)為undefined袜漩,表明這個(gè)參數(shù)是可以省略的
rest參數(shù)
用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對(duì)象了
rest 參數(shù)搭配的變量是一個(gè)數(shù)組湾碎,該變量將多余的參數(shù)放入數(shù)組中宙攻。
arguments對(duì)象不是數(shù)組,而是一個(gè)類(lèi)似數(shù)組的對(duì)象介褥。所以為了使用數(shù)組的方法座掘,必須使用Array.prototype.slice.call先將其轉(zhuǎn)為數(shù)組。rest 參數(shù)就不存在這個(gè)問(wèn)題柔滔,它就是一個(gè)真正的數(shù)組
rest 參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù))溢陪,否則會(huì)報(bào)錯(cuò)
函數(shù)的length屬性,不包括 rest 參數(shù)
name屬性
函數(shù)的name屬性睛廊,返回該函數(shù)的函數(shù)名形真。
bind返回的函數(shù),name屬性值會(huì)加上bound前綴
箭頭函數(shù)
使用一個(gè)圓括號(hào)代表參數(shù)部分
如果箭頭函數(shù)的代碼塊部分多于一條語(yǔ)句超全,就要使用大括號(hào)將它們括起來(lái)没酣,并且使用return語(yǔ)句返回
由于大括號(hào)被解釋為代碼塊卵迂,所以如果箭頭函數(shù)直接返回一個(gè)對(duì)象,必須在對(duì)象外面加上括號(hào)见咒,否則會(huì)報(bào)錯(cuò)
箭頭函數(shù)中的this
函數(shù)體內(nèi)的this對(duì)象偿衰,就是定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象改览。
箭頭函數(shù)中下翎,this
是固定的
this指向的固定化,并不是因?yàn)榧^函數(shù)內(nèi)部有綁定this的機(jī)制宝当,實(shí)際原因是箭頭函數(shù)根本沒(méi)有自己的this视事,導(dǎo)致內(nèi)部的this就是外層代碼塊的this。正是因?yàn)樗鼪](méi)有this庆揩,所以也就不能用作構(gòu)造函數(shù)
箭頭函數(shù)嵌套
數(shù)組的擴(kuò)展
擴(kuò)展運(yùn)算符
擴(kuò)展運(yùn)算符(spread)是三個(gè)點(diǎn)(...)俐东。它好比 rest 參數(shù)的逆運(yùn)算跌穗,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列
console.log(...[1, 2, 3]) // 1 2 3
Array.from()
Array.from方法用于將兩類(lèi)對(duì)象轉(zhuǎn)為真正的數(shù)組:類(lèi)似數(shù)組的對(duì)象(array-like object)和可遍歷(iterable)的對(duì)象
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的寫(xiě)法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的寫(xiě)法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.of()
Array.of方法用于將一組值,轉(zhuǎn)換為數(shù)組
數(shù)組實(shí)例的 copyWithin()
數(shù)組實(shí)例的 find() 和 findIndex()
數(shù)組實(shí)例的 fill()
fill方法使用給定值虏辫,填充一個(gè)數(shù)組
數(shù)組實(shí)例的 entries()蚌吸,keys() 和 values()
數(shù)組實(shí)例的 includes()
Array.prototype.includes方法返回一個(gè)布爾值,表示某個(gè)數(shù)組是否包含給定的值
數(shù)組的空位
對(duì)象的擴(kuò)展
ES6 允許在對(duì)象之中砌庄,直接寫(xiě)變量羹唠。這時(shí),屬性名為變量名, 屬性值為變量的值
屬性簡(jiǎn)寫(xiě)
const foo = 'bar';
const baz = {foo}; // {foo: "bar"}
const baz = {foo: foo};
方法簡(jiǎn)寫(xiě)
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
屬性名表達(dá)式
let obj = {
[lastWord]: 'world',
['h' + 'ello']() {
return 'hi';
}
};
const foo = 'bar';
const baz = { [foo]: 'abc'}; //{bar: "abc"}
const a={foo} //{foo: "bar"}
方法的 name 屬性
Object.is()
Object.assign()
屬性的可枚舉性和遍歷
Object.getOwnPropertyDescriptors()
super 關(guān)鍵字
關(guān)鍵字super娄昆,指向當(dāng)前對(duì)象的原型對(duì)象
super關(guān)鍵字表示原型對(duì)象時(shí)佩微,只能用在對(duì)象的方法之中,用在其他地方都會(huì)報(bào)錯(cuò)萌焰。
Object.keys()哺眯,Object.values(),Object.entries()
Symbol
作為屬性名的 Symbol
Symbol 值作為對(duì)象屬性名時(shí)杆怕,不能用點(diǎn)運(yùn)算符
點(diǎn)運(yùn)算符后面總是字符串,所以不會(huì)讀取mySymbol作為標(biāo)識(shí)名所指代的那個(gè)值
使用 Symbol 值定義屬性時(shí)壳贪,Symbol 值必須放在方括號(hào)之中陵珍。
Symbol.for(),Symbol.keyFor()
Set 和 Map 數(shù)據(jù)結(jié)構(gòu)
set
Set類(lèi)似于數(shù)組违施,但是成員的值都是唯一的互纯,沒(méi)有重復(fù)的值。
Set 本身是一個(gè)構(gòu)造函數(shù)磕蒲,用來(lái)生成 Set 數(shù)據(jù)結(jié)構(gòu)
WeakSet
WeakSet結(jié)構(gòu)與 Set 類(lèi)似留潦,也是不重復(fù)的值的集合。但是辣往,它與 Set 有兩個(gè)區(qū)別兔院。
首先,WeakSet 的成員只能是對(duì)象站削,而不能是其他類(lèi)型的值