小伙伴大多數(shù)還在使用ES5來進(jìn)行編寫举畸,使用ES5這無可厚非涵防,因?yàn)镋S5畢竟還是主流俄周,速度也更快星澳,但ES6引入的新特性是ES5無法比擬的疚顷,接下來分享一下我掌握的es6 也為自己做個總結(jié)
ES6搭建環(huán)境(與語法沒什么關(guān)系 可忽略)
現(xiàn)在的Chrome瀏覽器已經(jīng)支持ES6了,但是有些低版本的瀏覽器還是不支持ES6的語法禁偎,這就需要我們把ES6的語法自動的轉(zhuǎn)變成ES5的語法腿堤。
webpack
是有自動編譯轉(zhuǎn)換能力的,除了Webpack自動編譯如暖,我們還可以用Babel來完成
只用Babel做很簡單的配置哈笆檀,想深入的可以觀看阮一峰大大的日志
第一步配置 快速構(gòu)建package.json
npm init -y
安裝 babel
npm install -g babel-cli
安裝之后 再次安裝
npm install --save-dev babel-preset-es2015 babel-cli
安裝完成之后看看package.json 先 不要慌
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-preset-es2015": "^6.24.1"
}
接著在根目錄下 新建
.babelrc
擔(dān)心小伙伴懵逼 截個圖
在文件中寫入下方代碼
{
"presets":[
"es2015"
],
"plugins":[]
}
新建src 目錄 新建html 與 js ,再新建dist 目錄 新建js
注意此時 我們在html中引入的是dist中的js 我們不動dist中的js 編輯src下的js
在src下的js中編輯 使用es6語法
let a=1;
console.log(a);
然后我們在終端輸入
babel src/index.js -o dist/index.js
這句代碼意思就是 把src下的index.js 轉(zhuǎn)譯到dist下的index.js中 此時我們查看dist下的index.js
此時es5語法的js已經(jīng)自動生成 控制臺也能看到1的輸出
每次的編譯都需要轉(zhuǎn)換輸入命令有點(diǎn)煩盒至,可以配置一下package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel src/index.js -o dist/index.js"
},
修改好后酗洒,以后我們就可以使用 npm run build 來進(jìn)行轉(zhuǎn)換了。
沒學(xué)過webpack的小伙伴可以嘗試一下環(huán)境的安裝
正式進(jìn)入ES6 (想了解前后代碼變化可以使用我上面的環(huán)境安裝枷遂,編譯之前記得npm run build )
ES6中新的聲明方式
1.var:它是variable的簡寫樱衷,可以理解成變量的意思。
2.let:它在英文中是“讓”的意思登淘,也可以理解為一種聲明的意思。
3.const:它在英文中也是常量的意思封字,在ES6也是用來聲明常量的黔州,常量你可以簡單理解為不變的量耍鬓。
var聲明
var在ES6里是用來升級全局變量的,我們可以先作一個最簡單的實(shí)例流妻,用var聲明一個變量a,然后用console.log進(jìn)行輸出牲蜀。
var a="ES6";
window.onload= function(){
console.log(a);
}
可以看到控制臺輸出了ES6,這證明var確實(shí)是全局的绅这。如果你覺的這個不夠直觀說明var是全局聲明涣达,還可以用區(qū)塊的方式進(jìn)行調(diào)用測試,先看下面的代碼证薇。
var a=2;
{
var a=3;
}
console.log(a);
這時打印出來的值是多少那度苔?對,應(yīng)該是3浑度,因?yàn)関ar是全局聲明的寇窑。覆蓋了上面的2
let局部聲明
通過兩個簡單的例子,我們對var的全局聲明有了一定了解箩张。那跟var向?qū)?yīng)的是let甩骏,它是局部變量聲明。還是上面的例子先慷,我們試著在區(qū)塊里用let聲明饮笛。
var a=2;
{
let a=3;
}
console.log(a);
這時候控制臺打印出來的值就是2了。如果我們只在區(qū)塊里聲明论熙,不再外部聲明福青,我們打印a時就會報(bào)錯,顯示找不到變量赴肚。
{
let a=3;
}
console.log(a);
有些小伙伴可能會以為輸出undefined 其實(shí)是報(bào)錯了 a并沒有被聲明
有些剛接觸JavaScript的小伙伴會疑惑了素跺,我感覺let還沒有var好用,其實(shí)let是防止你的數(shù)據(jù)污染的誉券,在大型項(xiàng)目中是非常有用處的≈秆幔現(xiàn)在看一個循環(huán)的例子,我們來看一下let的好處踊跟。
用var聲明的循環(huán)
for(let i=0;i<10;i++){
console.log('循環(huán)體中:'+i);
}
console.log('循環(huán)體外:'+i);
你執(zhí)行時會發(fā)現(xiàn)控制臺報(bào)錯了踩验,找不到循環(huán)體外的i變量。通過兩種聲明的比較商玫,可以明白let在防止程序數(shù)據(jù)污染上還是很有用處的箕憾。我們要努力去習(xí)慣用let聲明,減少var聲明去污染全局空間拳昌,在vue的使用中也要注意這點(diǎn)袭异。
const聲明常量
在程序開發(fā)中,有些變量是希望聲明后在業(yè)務(wù)層就不再發(fā)生變化了炬藤,簡單來說就是從聲明開始御铃,這個變量始終不變碴里,就需要用const進(jìn)行聲明。
const a="ES6";
var a='ES6';
console.log(a);
在編譯這段代碼的過程中上真,你就會發(fā)現(xiàn)已經(jīng)報(bào)錯咬腋,無法編譯了,原因就是我們const聲明的變量是不可以改變的睡互。const是很好理解的根竿,我就不作過多的解釋說明了。
ES6變量的解構(gòu)賦值
簡單的數(shù)組解構(gòu)
以前就珠,為變量賦值寇壳,我們只能直接指定值。比如下面的代碼:
let a=0;
let b=1;
let c=2;
而現(xiàn)在我們可以用數(shù)組解構(gòu)的方式來進(jìn)行賦值嗓违。
let [a,b,c]=[1,2,3];
上面的代碼表示九巡,可以從數(shù)組中提取值,按照位置的對象關(guān)系對變量賦值蹂季。
數(shù)組模式和賦值模式統(tǒng)一
可以簡單的理解為等號左邊和等號右邊的形式要統(tǒng)一冕广,如果不統(tǒng)一解構(gòu)將失敗。
let [a,[b,c],d]=[1,[2,3],4];
如果等號兩邊形式不一樣偿洁,很可能獲得undefined或者直接報(bào)錯撒汉。
解構(gòu)的默認(rèn)值
解構(gòu)賦值是允許你使用默認(rèn)值的,先看一個最簡單的默認(rèn)是的例子
let [foo = true] =[];
console.log(foo); //控制臺打印出true
上邊的例子數(shù)組中只有一個值涕滋,可能你會多少有些疑惑睬辐,我們就來個多個值的數(shù)組,并給他一些默認(rèn)值
let [a,b="ES6"]=['2016']
console.log(a+b); //控制臺顯示“2016ES6” a對應(yīng)2016 b對應(yīng)空 但是默認(rèn)值為ES6
現(xiàn)在我們對默認(rèn)值有所了解宾肺,需要注意的是undefined和null的區(qū)別溯饵。
let [a,b="2016"]=['ES6',undefined];
console.log(a+b); //控制臺顯示“ES62016”
undefined相當(dāng)于什么都沒有,b是默認(rèn)值锨用。
let [a,b="2016"]=['ES6',null];
console.log(a+b); //控制臺顯示“ES6null”
null相當(dāng)于有值丰刊,但值為null。所以b并沒有取默認(rèn)值增拥,而是解構(gòu)成了null啄巧。
對象的解構(gòu)賦值 解構(gòu)不僅可以用于數(shù)組,還可以用于對象掌栅。
let {foo,bar} = {foo:'ES6',bar:'2016'};
console.log(foo+bar); //控制臺打印出了“ES62016”
注意:對象的解構(gòu)與數(shù)組有一個重要的不同秩仆。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定猾封;而對象的屬性沒有次序澄耍,變量必須與屬性同名,才能取到正確的值。
圓括號的使用
如果在解構(gòu)之前就定義了變量齐莲,這時候你再解構(gòu)會出現(xiàn)問題卿城。下面是錯誤的代碼,編譯會報(bào)錯铅搓。
let foo;
{foo} ={foo:'ES6'};
console.log(foo);
要解決報(bào)錯,使程序正常搀捷,我們這時候只要在解構(gòu)的語句外邊加一個圓括號就可以了星掰。
let foo;
({foo} ={foo:'ES6'});
console.log(foo); //控制臺輸出ES6
字符串解構(gòu)
字符串也可以解構(gòu),這是因?yàn)槟壑郏藭r字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象氢烘。
const [a,b,c,d,e,f]="STRING";
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
console.log(f);
ES6的擴(kuò)展運(yùn)算符和rest運(yùn)算符
擴(kuò)展運(yùn)算符和rest運(yùn)算符,它們都是…(三個點(diǎn))家厌。它們可以很好的為我們解決參數(shù)和對象數(shù)組未知情況下的編程播玖,讓我們的代碼更健壯和簡潔。
對象擴(kuò)展運(yùn)算符(…)
當(dāng)編寫一個方法時饭于,我們允許它傳入的參數(shù)是不確定的蜀踏。這時候可以使用對象擴(kuò)展運(yùn)算符來作參數(shù),看一個簡單的列子:
function es6(...arg){
console.log(arg[0]);
console.log(arg[1]);
console.log(arg[2]);
console.log(arg[3]);
}
es6(1,2,3);
這時我們看到控制臺輸出了 1,2,3掰吕,undefined果覆,這說明是可以傳入多個值,并且就算方法中引用多了也不會報(bào)錯殖熟。
擴(kuò)展運(yùn)算符的用處
我們先用一個例子說明局待,我們聲明兩個數(shù)組arr1和arr2,然后我們把a(bǔ)rr1賦值給arr2菱属,然后我們改變arr2的值钳榨,你會發(fā)現(xiàn)arr1的值也改變了,因?yàn)槲覀冞@是對內(nèi)存堆棧的引用纽门,而不是真正的賦值薛耻。
let arr1=['www','baidu','com'];
let arr2=arr1;
console.log(arr2);
arr2.push('ES6');
console.log(arr1);
控制臺輸出:
["www", "baidu", "com"]
["www", "baidu", "com", "ES6"]
這是我們不想看到的,可以利用對象擴(kuò)展運(yùn)算符簡單的解決這個問題膜毁,現(xiàn)在我們對代碼進(jìn)行改造昭卓。
let arr1=['www','baidu','com'];
//let arr2=arr1;
let arr2=[...arr1];
console.log(arr2);
arr2.push('ES6');
console.log(arr2);
console.log(arr1);
現(xiàn)在控制臺預(yù)覽時,你可以看到我們的arr1并沒有改變瘟滨,簡單的擴(kuò)展運(yùn)算符就解決了這個問題候醒。
rest運(yùn)算符
如果你已經(jīng)很好的掌握了對象擴(kuò)展運(yùn)算符,那么理解rest運(yùn)算符并不困難杂瘸,它們有很多相似之處倒淫,甚至很多時候你不用特意去區(qū)分。它也用…(三個點(diǎn))來表示败玉,我們先來看一個例子敌土。
function es6(first,...arg){
console.log(arg.length);
}
es6(0,1,2,3,4,5,6,7);
這時候控制臺打印出了7坪圾,說明我們arg里有7個數(shù)組元素舟山,這就是rest運(yùn)算符的最簡單用法。
如何循環(huán)輸出rest運(yùn)算符
這里我們用for…of循環(huán)來進(jìn)行打印出arg的值 (也可以使用for...in 兩者沒區(qū)別...吧 其實(shí)是有的 有興趣可以自行百度一下)
function es6(first,...arg){
for(let val of arg){
console.log(val);
}
}
es6(0,1,2,3,4,5,6,7);
for…of的循環(huán)可以避免我們開拓內(nèi)存空間,增加代碼運(yùn)行效率觅彰,所以建議大家在以后的工作中使用for…of循環(huán)。有的小伙伴會說了猾蒂,反正最后要轉(zhuǎn)換成ES5幌羞,沒有什么差別,但是至少從代碼量上我們少打了一些單詞癌淮,這就是開發(fā)效率的提高躺坟。
ES6的數(shù)字操作(用的比較少,了解一下)
二進(jìn)制聲明:
let binary = 0B010101;
console.log(binary);
來看看es5的編譯
"use strict";
var binary = 21;
console.log(binary);
當(dāng)然命名二進(jìn)制還是很少啦
八進(jìn)制聲明:
let b=0o666;
console.log(b);
數(shù)字判斷和轉(zhuǎn)換
數(shù)字驗(yàn)證Number.isFinite( xx )
可以使用Number.isFinite( )來進(jìn)行數(shù)字驗(yàn)證乳蓄,只要是數(shù)字咪橙,不論是浮點(diǎn)型還是整形都會返回true,其他時候會返回false虚倒。
let a= 11/4;
console.log(Number.isFinite(a));//true
console.log(Number.isFinite('ES6'));//false
console.log(Number.isFinite(NaN));//false
console.log(Number.isFinite(undefined));//false
判斷是否為整數(shù)Number.isInteger(xx)
let a=123.1;
console.log(Number.isInteger(a)); //false
整數(shù)轉(zhuǎn)換Number.parseInt(xxx)和浮點(diǎn)型轉(zhuǎn)換Number.parseFloat(xxx)
let a='9.18';
console.log(Number.parseInt(a));
console.log(Number.parseFloat(a));
整數(shù)取值范圍操作
整數(shù)的操作是有一個取值范圍的美侦,它的取值范圍就是2的53次方。我們先用程序來看一下這個數(shù)字是什么.
let a = Math.pow(2,53)-1; =>有些大神連下面的那串?dāng)?shù)字都記得住 完全瑟瑟發(fā)抖
console.log(a); //9007199254740991
最大安全整數(shù)
consolec .log(Number.MAX_SAFE_INTEGER);
最小安全整數(shù)
console.log(Number.MIN_SAFE_INTEGER);
安全整數(shù)判斷isSafeInteger( )
let a= Math.pow(2,53)-1;
console.log(Number.isSafeInteger(a));//false
ES6中新增的數(shù)組知識(1)
JSON數(shù)組格式轉(zhuǎn)換
JSON的數(shù)組格式就是為了前端快速的把JSON轉(zhuǎn)換成數(shù)組的一種格式魂奥,我們先來看一下JSON的數(shù)組格式怎么寫音榜。
let json = {
'0': 'www',
'1': 'baidu',
'2': 'com',
length:3
}
這就是一個標(biāo)準(zhǔn)的JSON數(shù)組格式,跟普通的JSON對比是在最后多了一個length屬性捧弃。只要是這種特殊的json格式都可以輕松使用ES6的語法轉(zhuǎn)變成數(shù)組赠叼。在ES6中絕大部分的Array操作都存在于Array對象里。我們就用Array.from(xxx)來進(jìn)行轉(zhuǎn)換违霞。我們把上邊的JSON代碼轉(zhuǎn)換成數(shù)組嘴办,并打印在控制臺。
let json = {
'0': 'www',
'1': 'baidu',
'2': 'com',
length:3
}
let arr=Array.from(json);
console.log(arr) =>["www", "baidu", "com"]
Array.of()方法
它負(fù)責(zé)把一堆文本或者變量轉(zhuǎn)換成數(shù)組买鸽。在開發(fā)中我們經(jīng)常拿到了一個類似數(shù)組的字符串涧郊,需要使用eval來進(jìn)行轉(zhuǎn)換,如果你一個老手程序員都知道eval的效率是很低的眼五,它會拖慢我們的程序妆艘。這時候我們就可以使用Array.of方法。我們看下邊的代碼把一堆數(shù)字轉(zhuǎn)換成數(shù)組并打印在控制臺上
let arr =Array.of(3,4,5,6);
console.log(arr);
當(dāng)然它不僅可以轉(zhuǎn)換數(shù)字看幼,字符串也是可以轉(zhuǎn)換的批旺,看下邊的代碼:
let arr =Array.of('www','baidu','com');
console.log(arr);
find( )實(shí)例方法
所謂的實(shí)例方法就是并不是以Array對象開始的,而是必須有一個已經(jīng)存在的數(shù)組诵姜,然后使用的方法汽煮,這就是實(shí)例方法(不理解請看下邊的代碼,再和上邊的代碼進(jìn)行比對,你會有所頓悟)暇赤。這里的find方法是從數(shù)組中查找心例。在find方法中我們需要傳入一個匿名函數(shù),函數(shù)需要傳入三個參數(shù)
value:表示當(dāng)前查找的值鞋囊。
index:表示當(dāng)前查找的數(shù)組索引止后。
arr:表示當(dāng)前數(shù)組。
在函數(shù)中如果找到符合條件的數(shù)組元素就進(jìn)行return溜腐,并停止查找坯门。你可以拷貝下邊的代碼進(jìn)行測試,就會知道find作用逗扒。
熟悉ES5新數(shù)組方法的小伙伴應(yīng)該很清楚啊
let arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.find(function(value,index,arr){
return value > 5;
}))
控制臺輸出了6,說明找到了符合條件的值欠橘,并進(jìn)行返回了矩肩,如果找不到會顯示undefined∷嘈可以利用這一特性判斷數(shù)據(jù)是否重復(fù)
ES6中新增的數(shù)組知識(2)
fill( )實(shí)例方法
fill()也是一個實(shí)例方法黍檩,它的作用是把數(shù)組進(jìn)行填充,它接收三個參數(shù)始锚,第一個參數(shù)是填充的變量刽酱,第二個是開始填充的位置,第三個是填充到的位置(可以根據(jù)自己理解用索引還是用位置來記)
let arr=[0,1,2,3,4,5,6,7,8,9];
arr.fill('ES6',2,5);
console.log(arr); =>[0, 1, "ES6", "ES6", "ES6", 5, 6, 7, 8, 9]
數(shù)組的遍歷 for…of循環(huán)
先來看一個最簡單的for…of循環(huán)
let arr=['www','baidu','com']
for (let item of arr){
console.log(item);
}
for…of數(shù)組索引:有時候開發(fā)中是需要數(shù)組的索引的瞧捌,那我們可以使用下面的代碼輸出數(shù)組索引
let arr=['www','baidu','com']
for (let index of arr.keys()){
console.log(index);
}
entries( )實(shí)例方法
entries()實(shí)例方式生成的是Iterator形式的數(shù)組棵里,那這種形式的好處就是可以讓我們在需要時用next()手動跳轉(zhuǎn)到下一個值。我們來看下面的代碼:
let arr=['www','baidu','com']
let list=arr.entries();
console.log(list.next().value); =>打印的是索引+值 構(gòu)成的數(shù)組
console.log(list.next().value);
console.log(list.next().value);
同時輸出數(shù)組的內(nèi)容和索引:我們用entries()這個實(shí)例方法姐呐,配合我們的for…of循環(huán)就可以同時輸出內(nèi)容和索引了
let arr=['www','baidu','com']
for (let [index,val] of arr.entries()){
console.log(index+':'+val);
}
=>注意此處乃是實(shí)例方法殿怜,并不是數(shù)組方法
ES6中的箭頭函數(shù)和擴(kuò)展
看一下ES5中的函數(shù)寫法先
function add(a,b){
return a+b;
}
console.log(add(1,2));
我們聲明了一個add函數(shù),然后傳入a和b兩個值曙砂,返回a+b的值头谜。 然后我們在控制臺打印了這個函數(shù)的返回結(jié)果,這里是3.
默認(rèn)值
在ES6中給我們增加了默認(rèn)值的操作鸠澈,我們修改上邊的代碼柱告,可以看到現(xiàn)在只需要傳遞一個參數(shù)也是可以正常運(yùn)行的
function add(a,b=1){
return a+b;
}
console.log(add(1));
有人覺得好像ES5也可以,我們來看看ES5的代碼
"use strict";
function add(a) {
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
return a + b;
}
console.log(add(1));
主動拋出錯誤
在使用Vue的框架中笑陈,可以經(jīng)臣识龋看到框架主動拋出一些錯誤,比如v-for必須有:key值涵妥。那尤大神是如何做到的那甲脏?其實(shí)很簡單,ES6中我們直接用throw new Error( xxxx ),就可以拋出錯誤。
function add(a,b=1){
if(a == 0){
throw new Error('This is error')
}
return a+b;
}
console.log(add(0));
如果你使用的是谷歌瀏覽器 開啟了斷點(diǎn)模式 無法正常顯示我們設(shè)置的錯誤 需要關(guān)閉斷點(diǎn)
函數(shù)中的嚴(yán)謹(jǐn)模式
我們在ES中就經(jīng)常使用嚴(yán)謹(jǐn)模式來進(jìn)行編程块请,但是必須寫在代碼最上邊娜氏,相當(dāng)于全局使用。在ES6中我們可以寫在函數(shù)體中墩新,相當(dāng)于針對函數(shù)來使用贸弥。
function add(a,b=1){
'use strict'
if(a == 0){
throw new Error('This is error');
}
return a+b;
}
console.log(add(1));
上邊的代碼如果運(yùn)行的話,你會發(fā)現(xiàn)瀏覽器控制臺報(bào)錯海渊,這是ES6中的一個坑绵疲,如果沒人指導(dǎo)的話,可能你會陷進(jìn)去一會臣疑。這個錯誤的原因就是如果你使用了默認(rèn)值盔憨,再使用嚴(yán)謹(jǐn)模式的話,就會有沖突讯沈,所以我們要取消默認(rèn)值的操作郁岩,這時候你在運(yùn)行就正常了。
function add(a,b){
'use strict'
if(a == 0){
throw new Error('This is error');
}
return a+b;
}
console.log(add(1,2));
獲得需要傳遞的參數(shù)個數(shù)
如果你在使用別人的框架時缺狠,不知道別人的函數(shù)需要傳遞幾個參數(shù)怎么辦问慎?ES6為我們提供了得到參數(shù)的方法(xxx.length).我們用上邊的代碼看一下需要傳遞的參數(shù)個數(shù)。
function add(a,b){
'use strict'
if(a == 0){
throw new Error('This is error');
}
return a+b;
}
console.log(add.length);
箭頭函數(shù)
這個有多實(shí)用就不用多說了吧
{}的使用
在箭頭函數(shù)中挤茄,方法體內(nèi)如果是兩句話如叼,那就需要在方法體外邊加上{}括號。例如下邊的代碼就必須使用{}.
var add =(a,b=1) => {
console.log('ES6')
return a+b;
};
console.log(add(1));
對比一下穷劈,箭頭函數(shù) 其實(shí)省略了 function { } 以及return 如果方法體內(nèi)是一句話的話
var add=(a)=>console.log(a)
add(3)
箭頭函數(shù)中不可加new笼恰,也就是說箭頭函數(shù)不能當(dāng)構(gòu)造函數(shù)進(jìn)行使用
ES6中的函數(shù)和數(shù)組補(bǔ)漏
對象的函數(shù)解構(gòu)
我們在前后端分離時,后端經(jīng)常返回來JSON格式的數(shù)據(jù)歇终,前端的美好愿望是直接把這個JSON格式數(shù)據(jù)當(dāng)作參數(shù)挖腰,傳遞到函數(shù)內(nèi)部進(jìn)行處理。ES6就為我們提供了這樣的解構(gòu)賦值练湿。
let json = {
a:'baidu',
b:'guge'
}
function fun({a,b='guge'}){
console.log(a,b);
}
fun(json);
數(shù)組的函數(shù)解構(gòu)
函數(shù)能解構(gòu)JSON猴仑,那解構(gòu)我們的數(shù)組就更不在話下了,我們看下邊的代碼肥哎。我們聲明一個數(shù)組辽俗,然后寫一個方法,最后用…進(jìn)行解構(gòu)賦值篡诽。
let arr = ['baidu','guge','sougou'];
function fun(a,b,c){
console.log(a,b,c);
}
fun(...arr); =>之前提到過 是不是記到了呢
in的用法
in是用來判斷對象或者數(shù)組中是否存在某個值的崖飘。我們先來看一下用in如何判斷對象里是否有某個值。
對象判斷
let obj={
a:'baidu',
b:'guge'
}
console.log('a' in obj); //true
數(shù)組判斷
先來看一下ES5判斷的弊端杈女,以前會使用length屬性進(jìn)行判斷朱浴,為0表示沒有數(shù)組元素吊圾。但是這并不準(zhǔn)確,或者說真實(shí)開發(fā)中有弊端翰蠢。
let arr=[,,,,,];
console.log(arr.length); //5
上邊的代碼輸出了5项乒,但是數(shù)組中其實(shí)全是空值,這就是一個坑啊梁沧。那用ES6的in就可以解決這個問題
let arr=[,,,,,];
console.log(0 in arr); //false
let arr1=['baidu','guge'];
console.log(0 in arr1); // true
注意:這里的0指的是數(shù)組下標(biāo)位置是否為空
因?yàn)閿?shù)組是有序的集合檀何,而對象是無序的,所以我們只能通過屬性判斷對象廷支,可以使用下標(biāo)索引判斷數(shù)組
ES6中對象
對象對于Javascript是非常重要的频鉴。在ES6中對象有了很多新特性
對象賦值
ES6允許把聲明的變量直接賦值給對象,我們看下面的例子
let name="js666";
let skill= 'web';
var obj= {name,skill};
console.log(obj); //Object {name: "js666", skill: "web"}
對象Key值構(gòu)建
有時候我們會在后臺取出key值恋拍,而不是我們前臺定義好的垛孔,這時候我們?nèi)绾螛?gòu)建我們的key值那。比如我們在后臺取了一個key值施敢,然后可以用[ ] 的形式周荐,進(jìn)行對象的構(gòu)建。
let key='skill';
var obj={
[key]:'web'
}
console.log(obj.skill);
自定義對象方法
對象方法就是把對象中的屬性悯姊,用匿名函數(shù)的形式編程方法
var obj={
add:function(a,b){
return a+b;
}
} 這個應(yīng)該很好理解哈
console.log(obj.add(1,2)); //3
Object.is( ) 對象比較
對象的比較方法,以前進(jìn)行對象值的比較,經(jīng)常使用===來判斷贩毕,比如下面的代碼
var obj1 = {name:'js'};
var obj2 = {name:'js'};
console.log(obj1.name === obj2.name);//true.
那ES6為我們提供了is方法進(jìn)行對比
var obj1 = {name:'js'};
var obj2 = {name:'js'};
console.log(obj1.name === obj2.name);//true
console.log(Object.is(obj1.name,obj2.name)); //true
區(qū)分=== 和 is方法的區(qū)別是什么悯许,看下面的代碼輸出結(jié)果
console.log(+0 === -0); //true
console.log(NaN === NaN ); //false
console.log(Object.is(+0,-0)); //false
console.log(Object.is(NaN,NaN)); //true
是不是頭都炸了 詭異的一批 ===為同值相等,is()為嚴(yán)格相等
Object.assign( )合并對象
操作數(shù)組時我們經(jīng)常使用數(shù)組合并辉阶,那對象也有合并方法先壕,那就是assgin( )∽惶穑看一下啊具體的用法
var a={a:'www'};
var b={b:'baidu'};
var c={c:'com'};
let d=Object.assign(a,b,c)
console.log(d);
Symbol在對象中的作用
Symbol的打印
我們先聲明一個Symbol垃僚,然后我們在控制臺輸出一下
var g = Symbol('ES6');
console.log(g);
console.log(g.toString());
這時候我們仔細(xì)看控制臺是有區(qū)別的,沒有toString的是紅字规辱,toString的是黑字
Symbol在對象中的應(yīng)用
看一下如何用Symbol構(gòu)建對象的Key谆棺,并調(diào)用和賦值。
var es = Symbol();
var obj={
[es]:'666'
}
console.log(obj[es]);
obj[es]='web';
console.log(obj[es]);
Symbol對象元素的保護(hù)作用
在對象中有很多值罕袋,但是循環(huán)輸出時改淑,并不希望全部輸出,那我們就可以使用Symbol進(jìn)行保護(hù)浴讯。
沒有進(jìn)行保護(hù)的寫法
var obj={name:'javascript',skill:'web',age:18};
for (let item in obj){
console.log(obj[item]);
}
現(xiàn)在我不想別人知道我的年齡朵夏,這時候我就可以使用Symbol來進(jìn)行循環(huán)保護(hù)
let obj={name:'javascript',skill:'web'};
let age=Symbol();
obj[age]=18;
for (let item in obj){
console.log(obj[item]);
}
console.log(obj);=>當(dāng)然這里是可以顯示的
Set和WeakSet數(shù)據(jù)結(jié)構(gòu)
Set數(shù)據(jù)結(jié)構(gòu),注意這里不是數(shù)據(jù)類型榆纽,而是數(shù)據(jù)結(jié)構(gòu)仰猖。它是ES6中新的東西捏肢,并且很有用處。Set的數(shù)據(jù)結(jié)構(gòu)是以數(shù)組的形式構(gòu)建的饥侵。
Set的聲明
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
Set和Array 的區(qū)別是Set不允許內(nèi)部有重復(fù)的值鸵赫,如果有只顯示一個,相當(dāng)于去重爆捞。雖然Set很像數(shù)組奉瘤,但是他不是數(shù)組。
Set值的增刪查 追加add:
在使用Array的時候煮甥,可以用push進(jìn)行追加值盗温,那Set稍有不同,它用更語義化的add進(jìn)行追加
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
setArr.add('vue');
console.log(setArr); =>在后面會增加vue
刪除delete
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
setArr.add('vue');
console.log(setArr);
setArr.delete('vue');
console.log(setArr); //Set {"js", "css", "html"}
查找has
用has進(jìn)行值的查找成肘,返回的是true或者false卖局。
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
setArr.clear();
console.log(setArr);//清空
set的循環(huán) for…of…循環(huán):
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
for (let item of setArr){
console.log(item);
}
size屬性
size屬性可以獲得Set值的數(shù)量。
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
for (let item of setArr){
console.log(item);
}
console.log(setArr.size); //3
forEach循環(huán) 這真不是數(shù)組
console.log(Array.isArray(setArr))=>false
console.log(setArr instanceof Array)=>false
let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}
setArr.forEach((value)=>console.log(value));
WeakSet的聲明
let weakObj=new WeakSet();
let obj={a:'we',b:'love'}
weakObj.add(obj);
console.log(weakObj);
這里需要注意的是双霍,如果你直接在new 的時候就放入值砚偶,將報(bào)錯。
WeakSet里邊的值也是不允許重復(fù)的洒闸,我們來測試一下染坯。
let weakObj=new WeakSet();
let obj={a:'we',b:'love'}
let obj1=obj;
weakObj.add(obj);
weakObj.add(obj1);
console.log(weakObj);=>不變
在實(shí)際開發(fā)中Set用的比較多,WeakSet用的并不多丘逸,但是他對傳入值必須是對象作了很好的判斷单鹿,我們靈活應(yīng)用還是有一定的用處的。
map數(shù)據(jù)結(jié)構(gòu)
我們知道的數(shù)據(jù)結(jié)構(gòu)深纲,已經(jīng)有了json和set仲锄。那map有什么特點(diǎn)。
Json和map格式的對比
map的效率和靈活性更好
先來寫一個JSON湃鹊,這里我們用對象進(jìn)行模擬操作儒喊。
let json = {
name:'js',
skill:'web'
}
console.log(json.name);
但是這種反應(yīng)的速度要低于數(shù)組和map結(jié)構(gòu)。而且Map的靈活性要更好币呵,你可以把它看成一種特殊的鍵值對怀愧,但你的key可以設(shè)置成數(shù)組,值也可以設(shè)置成字符串余赢,讓它不規(guī)律對應(yīng)起來掸驱。
let json = {
name:'js',
skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
console.log(map);
當(dāng)然也可key字符串,value是對象没佑。我們調(diào)換一下位置毕贼,依然是符合map的數(shù)據(jù)結(jié)構(gòu)規(guī)范的。
let json = {
name:'js',
skill:'web'
}
console.log(json.name);
var map=new Map();
// map.set(json,'iam');
// console.log(map);
map.set('iam',json);
console.log(map);
map的增刪查 取值get
現(xiàn)在取json對應(yīng)的值蛤奢。
let json = {
name:'js',
skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
// console.log(map);
// map.set('iam',json);
// console.log(map);
console.log(map.get(json));
刪除delete
let json = {
name:'js',
skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
// console.log(map);
// map.set('iam',json);
// console.log(map);
map.delete(json);
console.log(map)
size屬性
console.log(map.size);
查找是否存在has
consolec .log(map.has('iam'))
清除所有元素clear
map.clear()
用Proxy進(jìn)行預(yù)處理
如果你學(xué)過Vue鬼癣,一定會知道鉤子函數(shù)陶贼,那如果你并沒有學(xué)習(xí)Vue,那這里簡單解釋一下什么是鉤子函數(shù)待秃。當(dāng)我們在操作一個對象或者方法時會有幾種動作拜秧,比如:在運(yùn)行函數(shù)前初始化一些數(shù)據(jù),在改變對象值后做一些善后處理章郁。這些都算鉤子函數(shù)枉氮,Proxy的存在就可以讓我們給函數(shù)加上這樣的鉤子函數(shù),也可以理解為在執(zhí)行方法前預(yù)處理一些代碼暖庄。你可以簡單的理解為他是函數(shù)或者對象的生命周期聊替。
Proxy的應(yīng)用可以使函數(shù)更加強(qiáng)大,業(yè)務(wù)邏輯更加清楚培廓,而且在編寫自己的框架或者通用組件時非常好用惹悄。
先來看看定義對象的方法。.
var obj={
add:function(val){
return val+10;
},
name:'javascript'
};
console.log(obj.add(100));
console.log(obj.name);
聲明了一個obj對象肩钠,增加了一個對象方法add和一個對象屬性name泣港,然后在控制臺進(jìn)行了打印
聲明Proxy
我們用new的方法對Proxy進(jìn)行聲明〖劢常可以看一下聲明Proxy的基本形式当纱。
new Proxy({},{})
需要注意的是這里是兩個花括號,第一個花括號就相當(dāng)于我們方法的主體踩窖,后邊的花括號就是Proxy代理處理區(qū)域坡氯,相當(dāng)于我們寫鉤子函數(shù)的地方。
現(xiàn)在把上邊的obj對象改成我們的Proxy形式毙石。
var obj={
add:function(val){
return val+10;
},
name:'javascript'
};
// console.log(obj.add(100));
// console.log(obj.name);
var pro = new Proxy({
add: function (val) {
return val + 10;
},
name: 'javascript'
}, {
get:function(target,key,property){
console.log('come in Get');
return target[key];
}
});
console.log(pro.name);
可以在控制臺看到結(jié)果廉沮,先輸出了come in Get颓遏。相當(dāng)于在方法調(diào)用前的鉤子函數(shù)徐矩。
get屬性
get屬性是在你得到某對象屬性值時預(yù)處理的方法,他接受三個參數(shù)
target:得到的目標(biāo)值
key:目標(biāo)的key值叁幢,相當(dāng)于對象的屬性
property:這個不太常用滤灯,用法還在研究中,還請大神指教留言曼玩。
set屬性
set屬性是值你要改變Proxy屬性值時鳞骤,進(jìn)行的預(yù)先處理。它接收四個參數(shù)黍判。
target:目標(biāo)值豫尽。
key:目標(biāo)的Key值。
value:要改變的值顷帖。
receiver:改變前的原始值美旧。
var pro = new Proxy({
add: function (val) {
return val + 10;
},
name: 'javascript'
}, {
get:function(target,key){
console.log('come in Get');
return target[key];
},
set:function(target,key,value,receiver){
console.log(` setting ${key} = ${value}`);
return target[key] = value;
}
});
console.log(pro.name);
pro.name='前端';
console.log(pro.name);
這里比較復(fù)雜 看清輸出順序 建議看專門講解此內(nèi)容的專欄進(jìn)行加深
其實(shí)proxy的知識是非常多的渤滞,這里我建議看阮一峰大神的《ES6》。我這里只能算是入門
promise的基本用法
promise執(zhí)行多步操作非常好用榴嗅,那我們就來模仿一個多步操作的過程妄呕,那就以吃飯為例吧。要想在家吃頓飯嗽测,是要經(jīng)過三個步驟的绪励。
洗菜做飯。
坐下來吃飯唠粥。
收拾桌子洗碗疏魏。
這個過程是有一定的順序的,你必須保證上一步完成厅贪,才能順利進(jìn)行下一步蠢护。我們可以在腦海里先想想這樣一個簡單的過程在ES5寫起來就要有多層的嵌套。那我們現(xiàn)在用promise來實(shí)現(xiàn)养涮。
let state=1;
function step1(resolve,reject){
console.log('1.開始-洗菜做飯');
if(state==1){
resolve('洗菜做飯--完成');
}else{
reject('洗菜做飯--出錯');
}
}
function step2(resolve,reject){
console.log('2.開始-坐下來吃飯');
if(state==1){
resolve('坐下來吃飯--完成');
}else{
reject('坐下來吃飯--出錯');
}
}
function step3(resolve,reject){
console.log('3.開始-收拾桌子洗完');
if(state==1){
resolve('收拾桌子洗完--完成');
}else{
reject('收拾桌子洗完--出錯');
}
}
new Promise(step1).then(function(val){
console.log(val);
return new Promise(step2);
}).then(function(val){
console.log(val);
return new Promise(step3);
}).then(function(val){
console.log(val);
return val;
});
Promis在現(xiàn)在的開發(fā)中使用率算是最高的葵硕,而且你面試前端都會考這個對象,大家一定要掌握好
class類的使用
我們在ES5中經(jīng)常使用方法或者對象去模擬類的使用贯吓,雖然可以實(shí)現(xiàn)功能懈凹,但是代碼并不優(yōu)雅,ES6為我們提供了類的使用悄谐。需要注意的是我們在寫類的時候和ES5中的對象和構(gòu)造函數(shù)要區(qū)分開來介评,不要學(xué)混了。
先聲明一個最簡單的coder類爬舰,類里只有一個name方法们陆,方法中打印出傳遞的參數(shù)。
class coder{
name(val){
console.log(val);
}
}
我們已經(jīng)聲明了一個類情屹,并在類里聲明了name方法坪仇,現(xiàn)在要實(shí)例化類,并使用類中的方法垃你。
class Coder{
name(val){
console.log(val);
}
}
let js= new Coder;
js.name('javascript');
類的多方法聲明
class Coder{
name(val){
console.log(val);
return val;
}
skill(val){
console.log(this.name('js')+':'+'Skill:'+val);
}
}
let js= new Coder;
js.name('javascript');
js.skill('web');
類的傳參
在類的參數(shù)傳遞中我們用constructor( )進(jìn)行傳參椅文。傳遞參數(shù)后可以直接使用this.xxx進(jìn)行調(diào)用。
class Coder{
name(val){
console.log(val);
return val;
}
skill(val){
console.log(this.name('js')+':'+'Skill:'+val);
}
constructor(a,b){
this.a=a;
this.b=b;
}
add(){
return this.a+this.b;
}
}
let js=new Coder(1,2);
console.log(js.add());
我們用constructor來約定了傳遞參數(shù)惜颇,然后用作了一個add方法皆刺,把參數(shù)相加。這和以前我們的傳遞方法有些不一樣凌摄,所以需要小伙伴們多注意下羡蛾。
class的繼承
class Coder{
name(val){
console.log(val);
return val;
}
skill(val){
console.log(this.name('js')+':'+'Skill:'+val);
}
constructor(a,b){
this.a=a;
this.b=b;
}
add(){
return this.a+this.b;
}
}
class htmler extends Coder{
}
let js=new htmler;
js.name('javascript');
聲明一個htmler的新類并繼承Coder類宜鸯,htmler新類里邊為空睛蛛,這時候我們實(shí)例化新類贺辰,并調(diào)用里邊的name方法蔼卡。結(jié)果也是可以調(diào)用到的。
ES6的模塊化開發(fā)可以參考我的另一篇文章
http://www.reibang.com/p/01f3c09324bb