ES6語法的學(xué)習(xí)

第1節(jié):ES6的開發(fā)環(huán)境搭建

Webpack是有自動編譯轉(zhuǎn)換能力的,除了Webpack自動編譯,我們還可以用Babel來完成。下面我們就使用Babel把ES6編譯成ES5。
建立工程目錄: 先建立一個項(xiàng)目的工程目錄,并在目錄下邊建立兩個文件夾:src和dist

src:書寫ES6代碼的文件夾,寫的js程序都放在這里。
dist:利用Babel編譯成的ES5代碼的文件夾,在HTML頁面需要引入的時這里的js文件。

編寫index.html:
文件夾建立好后,我們新建一個index.html文件。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="./dist/index.js"></script>
    </head>
    <body>
        Hello ECMA Script 6
    </body>
</html>

需要注意的是在引入js文件時,引入的是dist目錄下的文件。

<script src="./dist/index.js"></script>

在安裝Babel之前,需要用npm init先初始化我們的項(xiàng)目。打開終端或者通過cmd打開命令行工具,進(jìn)入項(xiàng)目目錄,輸入下邊的命令:npm init -y 。-y代表全部默認(rèn)同意,就不用一次次按回車了。命令執(zhí)行完成后,會在項(xiàng)目根目錄下生產(chǎn)package.json文件。

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

可以根據(jù)自己的需要進(jìn)行修改,比如我們修改name的值。

全局安裝Babel-cli
在終端中輸入以下命令,如果你安裝很慢的話,可以使用淘寶鏡像的cnpm來進(jìn)行安裝。安裝cnpm的方法,大家自己百度吧。

npm install -g babel-cli

雖然已經(jīng)安裝了babel-cli,只是這樣還不能成功進(jìn)行轉(zhuǎn)換,如果你不相信可以輸入下邊的命令試一下。

babel src/index.js -o dist/index.js

你會發(fā)現(xiàn),在dist目錄下確實(shí)生產(chǎn)了index.js文件,但是文件并沒有變化,還是使用了ES6的語法。因?yàn)槲覀冞€需要安裝轉(zhuǎn)換包才能成功轉(zhuǎn)換。需要本地安裝babel-preset-es2015 和 babel-cli

npm install --save-dev babel-preset-es2015 babel-cli

安裝完成后,我們可以看一下我們的package.json文件,已經(jīng)多了devDependencies選項(xiàng)。

"devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-preset-es2015": "^6.24.1"
  }

新建.babelrc
在根目錄下新建.babelrc文件,并打開錄入下面的代碼

{
    "presets":[
        "es2015"
    ],
    "plugins":[]
}

這個文件我們建立完成后,現(xiàn)在可以在終端輸入的轉(zhuǎn)換命令了,這次ES6成功轉(zhuǎn)化為ES5的語法。

babel src/index.js -o dist/index.js

簡化轉(zhuǎn)化命令:
在學(xué)習(xí)vue 的時候,可以使用npm run build 直接利用webpack進(jìn)行打包,在這里也希望利用這種方式完成轉(zhuǎn)換。打開package.json文件,把文件修改成下面的樣子。修改scripts里面的test變成"build": "babel src/index.js -o dist/index.js"

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "babel src/index.js -o dist/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-preset-es2015": "^6.24.1"
  }
}

修改好后,以后我們就可以使用 npm run build 來進(jìn)行轉(zhuǎn)換了。

第2節(jié):新的聲明方式

字面理解ES6的三種聲明方式:

  1. var:它是variable的簡寫,可以理解成變量的意思。
  2. let:let是局部變量聲明,let聲明只在區(qū)塊內(nèi)起作用,外部是不可以調(diào)用的。
  3. const:它在英文中也是常量的意思,在ES6也是用來聲明常量的,常量你可以簡單理解為不變的量。

第3節(jié):變量的解構(gòu)賦值

ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)。解構(gòu)賦值在實(shí)際開發(fā)中可以大量減少我們的代碼量,并且讓我們的程序結(jié)構(gòu)更清晰。

數(shù)組的解構(gòu)賦值:

1.簡單的數(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)系對變量賦值。

2.數(shù)組模式和賦值模式統(tǒng)一:

可以簡單的理解為等號左邊和等號右邊的形式要統(tǒng)一,如果不統(tǒng)一解構(gòu)將失敗。

let [a,[b,c],d]=[1,[2,3],4];

如果等號兩邊形式不一樣,很可能獲得undefined或者直接報錯。

解構(gòu)的默認(rèn)值:
解構(gòu)賦值是允許你使用默認(rèn)值的,先看一個最簡單的默認(rèn)是的例子。

let [foo = true] =[];
console.log(foo); //控制臺打印出true

上邊的例子數(shù)組中只有一個值,可能你會多少有些疑惑,我們就來個多個值的數(shù)組,并給他一些默認(rèn)值。

let [a,b="zyl"]=['朱一龍']
console.log(a+b); //控制臺顯示“朱一龍zyl”

現(xiàn)在我們對默認(rèn)值有所了解,需要注意的是undefined和null的區(qū)別。

let [a,b="zyl"]=['朱一龍',undefined];
console.log(a+b); //控制臺顯示“朱一龍zyl”

undefined相當(dāng)于什么都沒有,b是默認(rèn)值。

let [a,b="zyl"]=['朱一龍',null];
console.log(a+b); //控制臺顯示“朱一龍null”

null相當(dāng)于有值,但值為null。所以b并沒有取默認(rèn)值,而是解構(gòu)成了null。

對象的解構(gòu)賦值
解構(gòu)不僅可以用于數(shù)組,還可以用于對象。

let {foo,bar} = {foo:'zyl',bar:'朱一龍'};
console.log(foo+bar); //控制臺打印出了“zyl朱一龍”

注意:對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

圓括號的使用
如果在解構(gòu)之前就定義了變量,這時候你再解構(gòu)會出現(xiàn)問題。下面是錯誤的代碼,編譯會報錯。

let foo;
{foo} ={foo:'zyl'};
console.log(foo);

要解決報錯,使程序正常,我們這時候只要在解構(gòu)的語句外邊加一個圓括號就可以了。

let foo;
({foo} ={foo:'zyl'});
console.log(foo); //控制臺輸出zyl

字符串解構(gòu)
字符串也可以解構(gòu),這是因?yàn)?,此時字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象。

const [a,b,c,d,e,f]="JSPang";
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
console.log(f);

第4節(jié):擴(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 zyl(...arg){
    console.log(arg[0]);
    console.log(arg[1]);
    console.log(arg[2]);
    console.log(arg[3]);
 
}
zyl(1,2,3);

這時我們看到控制臺輸出了 1,2,3,undefined,這說明是可以傳入多個值,并且就算方法中引用多了也不會報錯。

擴(kuò)展運(yùn)算符的用處:
我們先用一個例子說明,我們聲明兩個數(shù)組arr1和arr2,然后我們把a(bǔ)rr1賦值給arr2,然后我們改變arr2的值,你會發(fā)現(xiàn)arr1的值也改變了,因?yàn)槲覀冞@是對內(nèi)存堆棧的引用,而不是真正的賦值。

let arr1= ['aa','bb','cc'];
let arr2=arr1
console.log(arr2)  //['aa','bb','cc']
arr2.push('dd')
console.log(arr1) //['aa','bb','cc','dd']

這是我們不想看到的,可以利用對象擴(kuò)展運(yùn)算符簡單的解決這個問題,現(xiàn)在我們對代碼進(jìn)行改造。

let list1 = ['忘羨','魏無羨','藍(lán)忘機(jī)']
let list2 = [...list1]
console.log(list2)
list2.push('朱一龍')
console.log(list2)
console.log(list1)

現(xiàn)在控制臺預(yù)覽時,你可以看到我們的arr1并沒有改變,簡單的擴(kuò)展運(yùn)算符就解決了這個問題。

rest運(yùn)算符
如果你已經(jīng)很好的掌握了對象擴(kuò)展運(yùn)算符,那么理解rest運(yùn)算符并不困難,它們有很多相似之處,甚至很多時候你不用特意去區(qū)分。它也用…(三個點(diǎn))來表示,我們先來看一個例子。

//rest ...運(yùn)算符
function hcy(first,...arg){
  // for(let i =0;i<arg.length;i++){
  //   console.log(arg[i]);
  // }
  //新寫法
  for(let val of arg){
    console.log(val);
  }
}
hcy(0,1,2,3,4,5,6,7)

for…of的循環(huán)可以避免我們開拓內(nèi)存空間,增加代碼運(yùn)行效率,所以建議大家在以后的工作中使用for…of循環(huán)。有的小伙伴會說了,反正最后要轉(zhuǎn)換成ES5,沒有什么差別,但是至少從代碼量上我們少打了一些單詞,這就是開發(fā)效率的提高。

第5節(jié):字符串模版

ES6對字符串新增的操作,字符串模版的出現(xiàn)讓我們再也不用拼接變量了,而且支持在模板里有簡單計算操作

字符串模版
先來看一個在ES5下我們的字符串拼接案例:

let zyl = '朱一龍';
let blog = '強(qiáng)大的字符串模版,在實(shí)際開發(fā)中,'+zyl+'可以讓后臺寫一個活動頁面,然后輕松的輸出給用戶。'
document.write(blog); 

ES5下必須用+zyl+這樣的形式進(jìn)行拼接,這樣很麻煩而且很容易出錯。ES6新增了字符串模版,可以很好的解決這個問題。字符串模版不再使用‘xxx’這樣的單引號,而是換成了xxx這種形式,也叫連接號。這時我們再引用zyl變量就需要用${zyl}這種形式了,我們對上邊的代碼進(jìn)行改造。

let zyl = '朱一龍';
let blog = `強(qiáng)大的字符串模版,在實(shí)際開發(fā)中,<br/>${zyl}可以讓后臺寫一個活動頁面,<br/>然后輕松的輸出給用戶。<br/>`
document.write(blog);

可以看到瀏覽器出現(xiàn)了和上邊代碼一樣的結(jié)果。而且這里邊支持html標(biāo)簽,可以試著輸入一些

對運(yùn)算的支持:

let a=1;
let b=2;
let result=`${a+b}`;
document.write(result);

強(qiáng)大的字符串模版,在實(shí)際開發(fā)中,我們可以讓后臺寫一個活動頁面,然后輕松的輸出給用戶。

字符串查找
ES6還增加了字符串的查找功能,而且支持中文哦。還是拿上邊的文字作例子,進(jìn)行操作。

  1. 查找是否存在:

先來看一下ES5的寫法,其實(shí)這種方法并不實(shí)用,給我們的索引位置,我們自己還要確定位置。

let hcy = '華晨宇'
let hh = '強(qiáng)大的字符串模版,在實(shí)際開發(fā)中,華晨宇可以讓后臺寫一個活動頁面,然后輕松的輸出給用戶。'
document.write(hh.includes(hcy)+'<br/>');  //true 判斷有沒有華晨宇字符
document.write(hh.startsWith(hcy)+'<br/>');  //false 判斷開頭有沒有
document.write(hh.endsWith(hcy)+'<br/>');  //false 判斷結(jié)尾有沒有

需要注意的是:starts和ends 后邊都要加s

  1. 復(fù)制字符串:

我們有時候是需要字符串重復(fù)的,比如分隔符和特殊符號,這時候復(fù)制字符串就派上用場了,語法很簡單。

document.write('朱一龍|'.repeat(3)+'<br/>');

第6節(jié):ES6數(shù)字操作

二進(jìn)制和八進(jìn)制
二進(jìn)制和八進(jìn)制數(shù)字的聲明并不是ES6的特性,我們只是做一個常識性的回顧

二進(jìn)制聲明
二進(jìn)制的英文單詞是Binary,二進(jìn)制的開始是0(零),然后第二個位置是b(注意這里大小寫都可以實(shí)現(xiàn)),然后跟上二進(jìn)制的值就可以了。

let binary = 0B010101;
console.log(binary); //21

八進(jìn)制聲明
八進(jìn)制的英文單詞是Octal,也是以0(零)開始的,然后第二個位置是O(歐),然后跟上八進(jìn)制的值就可以了。

let b=0o666;
console.log(b); //438

數(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('jspang'));//false
console.log(Number.isFinite(NaN));//false
console.log(Number.isFinite(undefined));//false

NaN驗(yàn)證
NaN是特殊的非數(shù)字,可以使用Number.isNaN()來進(jìn)行驗(yàn)證。下邊的代碼控制臺返回了true。

console.log(Number.isNaN(NaN)); //true

判斷是否為整數(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));      //9
console.log(Number.parseFloat(a));  //9.18

整數(shù)取值范圍操作
整數(shù)的操作是有一個取值范圍的,它的取值范圍就是2的53次方。我們先用程序來看一下這個數(shù)字是什么.

let a = Math.pow(2,53)-1;
console.log(a); //9007199254740991

在我們計算時會經(jīng)常超出這個值,所以我們要進(jìn)行判斷,ES6提供了一個常數(shù),叫做最大安全整數(shù),以后就不需要我們計算了。

最大安全整數(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

總結(jié):這節(jié)課我們學(xué)習(xí)了ES6數(shù)字的操作,方法很多,很零散,需要經(jīng)常復(fù)習(xí)或者實(shí)戰(zhàn)中慢慢熟悉。

第7節(jié):ES6中新增的數(shù)組知識(1)

JSON數(shù)組格式轉(zhuǎn)換
JSON的數(shù)組格式就是為了前端快速的把JSON轉(zhuǎn)換成數(shù)組的一種格式,我們先來看一下JSON的數(shù)組格式怎么寫。

let json = {
  '0' : 'zyl',
  '1' : 'dl',
  '2' : 'hcy',
  length:3
}

Array.from()方法
這就是一個標(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' : 'zyl',
  '1' : 'dl',
  '2' : 'hcy',
  length:3
}

let arr = Array.from(json);
console.log(arr)

實(shí)際開發(fā)中這種方法還是比較常用的,畢竟節(jié)省了我們代碼行數(shù),也讓我們的程序更清晰。

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);
//字符串也可以轉(zhuǎn)換
let arr4 = Array.of('朱一龍','華晨宇','魏無羨','藍(lán)忘機(jī)')
console.log(arr4) //['朱一龍','華晨宇','魏無羨','藍(lán)忘機(jī)']

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作用。
let arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.find(function(value,index,arr){
    return value > 5;
})) //6 查找到第一個就停止了

控制臺輸出了6,說明找到了符合條件的值,并進(jìn)行返回了,如果找不到會顯示undefined
字符串也可以查找

et list2 = ['zyl','dl','hh']
console.log(list2.find(function(val,index,arr){
  return val == 'dl'; //dl
}))

第8節(jié):ES6中新增的數(shù)組知識(2)

fill( )實(shí)例方法
fill()也是一個實(shí)例方法,它的作用是把數(shù)組進(jìn)行填充,它接收三個參數(shù),第一個參數(shù)是填充的變量,第二個是開始填充的位置,第三個是填充到的位置。

let ll = ['zly','xlb','hcy']
ll.fill('cpp',1,2)
console.log(ll)

上邊的代碼是把數(shù)組從第二位到第五位用cpp進(jìn)行填充。

數(shù)組的遍歷

1.for…of循環(huán):
這種形式比ES5的for循環(huán)要簡單而且高效。先來看一個最簡單的for…of循環(huán)

let ll = ['zly','xlb','hcy']
for(let item of ll){
  console.log(item) //zyl,xlb,hcy
}

for…of數(shù)組索引:有時候開發(fā)中是需要數(shù)組的索引的,那我們可以使用下面的代碼輸出數(shù)組索引。

let ll = ['zly','xlb','hcy']
for(let item of ll.keys()){
  console.log(item) //0,1,2
} 

可以看到這時的控制臺就輸出了0,1,2,也就是數(shù)組的索引。

同時輸出數(shù)組的內(nèi)容和索引:我們用entries()這個實(shí)例方法,配合我們的for…of循環(huán)就可以同時輸出內(nèi)容和索引了。

let ll = ['zly','xlb','hcy']
for(let [index,val] of ll.entries()){
  console.log(index+':'+val)
}

2.entries( )實(shí)例方法:
entries()實(shí)例方式生成的是Iterator形式的數(shù)組,那這種形式的好處就是可以讓我們在需要時用next()手動跳轉(zhuǎn)到下一個值。我們來看下面的代碼:

let arrays = ['zly','xlb','hcy'];
let arrayss = arrays.entries()
console.log(arrayss.next().value)
console.log('1111111111')
console.log(arrayss.next().value)
console.log('2222222222')
console.log(arrayss.next().value)
console.log('3333333333')

第9節(jié):ES6中的箭頭函數(shù)和擴(kuò)展

首先回顧下ES5中的函數(shù)寫法,寫一個函數(shù),進(jìn)行一個加法計算。

function add(a,b){
    return a+b;
}
console.log(add(1,2)); //3

默認(rèn)值
在ES6中給我們增加了默認(rèn)值的操作,我們修改上邊的代碼,可以看到現(xiàn)在只需要傳遞一個參數(shù)也是可以正常運(yùn)行的。

function add(a,b=1){
    return a+b;
}
console.log(add(1));

主動拋出錯誤
在使用Vue的框架中,可以經(jīng)??吹娇蚣苤鲃訏伋鲆恍╁e誤,比如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));

函數(shù)中的嚴(yán)謹(jǐn)模式
我們在ES5中就經(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));

獲得需要傳遞的參數(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); // 2

這時控制臺打印出了2,但是如果我們?nèi)サ魢?yán)謹(jǐn)模式,并給第二個參數(shù)加上默認(rèn)值的話,這時候add.length的值就變成了1, 也就是說它得到的是必須傳入的參數(shù)。

箭頭函數(shù)
在學(xué)習(xí)Vue的時候,我已經(jīng)大量的使用了箭頭函數(shù),因?yàn)榧^函數(shù)真的很好用,我們來看一個最簡單的箭頭函數(shù)。也就是上邊我們寫的add函數(shù),進(jìn)行一個改變,寫成箭頭函數(shù)。

var add = (a,b=1) => a+b;
console.log(add(1));

{}的使用
在箭頭函數(shù)中,方法體內(nèi)如果是兩句話,那就需要在方法體外邊加上{}括號。例如下邊的代碼就必須使用{}.

var add =(a,b=1) => {
    console.log('zyl')
    return a+b;
};
console.log(add(1));

箭頭函數(shù)中不可加new,也就是說箭頭函數(shù)不能當(dāng)構(gòu)造函數(shù)進(jìn)行使用。

第10節(jié):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:'zyl',
    b:'朱一龍'
}
function fun({a,b='zyl'}){
    console.log(a,b); // zyl 朱一龍
}
fun(json);

數(shù)組的函數(shù)解構(gòu)
函數(shù)能解構(gòu)JSON,那解構(gòu)我們的數(shù)組就更不在話下了,我們看下邊的代碼。我們聲明一個數(shù)組,然后寫一個方法,最后用…進(jìn)行解構(gòu)賦值。

let arrayA = ['zz','ll','hh'];
function funs(a,b,c){
  console.log(a,b,c) // zz ll hh
}
funs(...arrayA)

in的用法
in是用來判斷對象或者數(shù)組中是否存在某個值的。我們先來看一下用in如何判斷對象里是否有某個值。

1.對象判斷

let obj = {
  zyl:'朱一龍',
  dl:'鄧倫'
}
console.log('c' in obj) //false

2.數(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 arrsss = ['藍(lán)忘機(jī)',,]
console.log(0 in arrsss) //true 
console.log(1 in arrsss) //false 
注意:這里的0指的是數(shù)組下標(biāo)位置是否為空。

數(shù)組的遍歷方法

//1.forEach
let arrB = ['藍(lán)湛','魏嬰','藍(lán)渙']
arrB.forEach((val, index) => console.log(index,val)) //0 "藍(lán)湛" 1 "魏嬰" 2 "藍(lán)渙"

forEach循環(huán)的特點(diǎn)是會自動省略為空的數(shù)組元素,相當(dāng)于直接給我們篩空了。當(dāng)是有時候也會給我們幫倒忙。

//2.filter some map(替換作用)
let arrC = ['藍(lán)忘機(jī)','魏無羨','藍(lán)曦臣']
let arrD = ['含光君','夷陵老祖','澤蕪君']
arrC.filter(x => console.log(x)) //藍(lán)忘機(jī) 魏無羨 藍(lán)曦臣
arrD.some(x => console.log(x)) //含光君 夷陵老祖 澤蕪君
console.log(arrD.map(x => '魔道祖師'))  // ["魔道祖師", "魔道祖師", "魔道祖師"]

第11節(jié):ES6中對象

對象對于Javascript是非常重要的。在ES6中對象有了很多新特性。

對象賦值
ES6允許把聲明的變量直接賦值給對象,我們看下面的例子。

let name = '藍(lán)湛'
let skill = '弦殺術(shù)'
let obja = {name:name,skill:skill}
console.log(obja) //{name: "藍(lán)湛", skill: "弦殺術(shù)"}
let objb = {name,skill}
console.log(objb ) //{name: "藍(lán)湛", skill: "弦殺術(shù)"}

對象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);

自定義對象方法
對象方法就是把兌現(xiàn)中的屬性,用匿名函數(shù)的形式編程方法。

var obj={
    add:function(a,b){
        return a+b;
    }
}
console.log(obj.add(1,2));  //3

Object.is( ) 對象比較
對象的比較方法,以前進(jìn)行對象值的比較,經(jīng)常使用===來判斷,ES6為我們提供了is方法進(jìn)行對比,比如下面的代碼:

let obj1 = {name:'魏無羨'}
let obj2 = {name:'魏無羨'}
console.log(obj1.name === obj2.name) //true
console.log(Object.is(obj1.name,obj2.name)) //true

區(qū)分=== 和 is方法的區(qū)別是什么,看下面的代碼輸出結(jié)果。

console.log(+00 === -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( )。看一下啊具體的用法。

let lwj = {lwj : '含光君'}
let wwx = {wwx : '魏無羨'}
let lxc = {lxc : '藍(lán)曦臣'}
let d = Object.assign(lwj,wwx,lxc)
console.log(d) //{lwj: "含光君", wwx: "魏無羨", lxc: "藍(lán)曦臣"}

第12節(jié):Symbol在對象中的作用

我們通過場景應(yīng)用的方式學(xué)習(xí)Symbol,它的意思是全局標(biāo)記。我們先看看它的聲明方式。

聲明Symbol
我們先來回顧一下我們的數(shù)據(jù)類型,在最后在看看Symbol如何聲明,并進(jìn)行一個數(shù)據(jù)類型的判斷。

var a = new String;
var b = new Number;
var c = new Boolean;
var d = new Array;
var e = new Object; 
let f = Symbol()
console.log(typeof(a)) //object
console.log(typeof(f)) //symbol

Symbol的打印
我們先聲明一個Symbol,然后我們在控制臺輸出一下。

let cpp = Symbol('朱一龍')
console.log(cpp); //symbol類型
console.log(cpp.toString(cpp)) //字符串

這時候我們仔細(xì)看控制臺是有區(qū)別的,沒有toString的是紅字,toString的是黑字。

Symbol在對象中的應(yīng)用
看一下如何用Symbol構(gòu)建對象的Key,并調(diào)用和賦值。

let hgj = Symbol()
 let objH = {
   [hgj]:'含光君'
 }
 console.log(objH[hgj]) //含光君
 objH[hgj] = '藍(lán)忘機(jī)';
 console.log(objH[hgj]) //藍(lán)忘機(jī)

Symbol對象元素的保護(hù)作用
在對象中有很多值,但是循環(huán)輸出時,并不希望全部輸出,那我們就可以使用Symbol進(jìn)行保護(hù)。
沒有進(jìn)行保護(hù)的寫法:

let wy = {name:'魏嬰',skill:'鬼道',love:'藍(lán)湛'};
for (let item in wy ){
    console.log(wy [item]);
}

現(xiàn)在我不想別人知道我的love,這時候我就可以使用Symbol來進(jìn)行循環(huán)保護(hù)。

let wy = {name:'魏嬰',skill:'鬼道'};
 let love = Symbol();
 wy[love] = "藍(lán)湛";
 console.log(wy) //{name: "魏嬰", skill: "鬼道", Symbol(): "藍(lán)湛"}

 //循環(huán)輸出對象
 for (let item in wy){
   console.log(wy[item]) //魏嬰 鬼道
 }

第13節(jié):Set和WeakSet數(shù)據(jù)結(jié)構(gòu)

這節(jié)學(xué)習(xí)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(['江厭離','魏無羨','江晚吟']);
console.log(setArr) //Set(3) {"江厭離", "魏無羨", "江晚吟"}

SetArray的區(qū)別是Set不允許內(nèi)部有重復(fù)的值,如果有只顯示一個,相當(dāng)于去重。雖然Set很像數(shù)組,但是他不是數(shù)組。

Set值的增刪查
1.追加add()
在使用Array的時候,可以用push進(jìn)行追加值,那Set稍有不同,它用更語義化的add進(jìn)行追加。

let setArr = new Set(['江厭離','魏無羨','江晚吟']);
setArr.add('金子軒')
console.log(setArr) // Set(4) {"江厭離", "魏無羨", "江晚吟", "金子軒"}

2.刪除單個值 delete()

let setArr = new Set(['江厭離','魏無羨','江晚吟', "金子軒"]);
setArr.delete('江晚吟')
console.log(setArr) //Set(3) {"江厭離", "魏無羨", "金子軒"}

3.查找值 has()
用has進(jìn)行值的查找,返回的是true或者false。

let setArr = new Set(['江厭離','魏無羨', "金子軒"]);
console.log(setArr.has('曉星塵')) //false

4.刪除全部的值 clear()

let setArr = new Set(['江厭離','魏無羨', "金子軒"]);
setArr.clear()
console.log(setArr) //Set(0) {}

set的循環(huán) for…of…循環(huán)和forEach循環(huán):

//for…of…
let setArr2 = new Set(['江厭離','魏無羨','江晚吟']);
for(let item of setArr2){
  console.log(item) // 江厭離 魏無羨 江晚吟
}
//forEach循環(huán)
setArr2.forEach((value) => console.log(value)) // 江厭離 魏無羨 江晚吟

size屬性
size屬性可以獲得Set值的數(shù)量。

let setArr2 = new Set(['江厭離','魏無羨','江晚吟']);
console.log(setArr2.size) //3

WeakSet的聲明
WeakSet 可以放對象 需要add添加值

let weakObj = new WeakSet();
let wobj = {k:'聶懷桑',j:'聶明玦'}
let wobj1 = {k:'聶懷桑',j:'聶明玦'}
weakObj.add(wobj);
weakObj.add(wobj1);
console.log(weakObj)

這里需要注意的是,如果你直接在new 的時候就放入值,將報錯。WeakSet里邊的值也是不允許重復(fù)的

第14節(jié):map數(shù)據(jù)結(jié)構(gòu)

這節(jié)課主要學(xué)習(xí)map的這種ES6新加的數(shù)據(jù)結(jié)構(gòu)。在一些構(gòu)建工具中是非常喜歡使用map這種數(shù)據(jù)結(jié)構(gòu)來進(jìn)行配置的,因?yàn)閙ap是一種靈活,簡單的適合一對一查找的數(shù)據(jù)結(jié)構(gòu)。我們知道的數(shù)據(jù)結(jié)構(gòu),已經(jīng)有了json和set。那map有什么特點(diǎn)。

Json和map格式的對比
map的效率和靈活性更好。
先來寫一個JSON,這里我們用對象進(jìn)行模擬操作。

let jsonZyl = {
  name:'zyl',
  age:'32'
}
console.log(jsonZyl.name) //效率慢

但是這種反應(yīng)的速度要低于數(shù)組和map結(jié)構(gòu)。而且Map的靈活性要更好,你可以把它看成一種特殊的鍵值對,但你的key可以設(shè)置成數(shù)組,值也可以設(shè)置成字符串,讓它不規(guī)律對應(yīng)起來。

let jsonZyl = {
  name:'zyl',
  age:'32'
}
//=> 靈活的改變key值和value值 賦值用set()
let map = new Map();
map.set(jsonZyl,'love')
console.log(map) //{Object => "love"} key: {name: "zyl", age: "32"} value: "love"
map.set('朱一龍',jsonZyl)
console.log(map) //{"朱一龍" => Object} key: "朱一龍" value: {name: "zyl", age: "32"}

map的增刪查
上邊我們已經(jīng)會為map增加值了,就是用我們的set方法。

1.取值用get()

console.log(map.get(jsonZyl)) //取到value值 love
console.log(map.get('朱一龍')) //取到value值 {name: "zyl", age: "32"}

2.查看里面有多少值 size屬性不要括號

console.log(map.size) //2

3.刪除單個值 delete()

map.delete(jsonZyl)
console.log(map) //0: {"朱一龍" => Object}

3.刪除全部的值clear()

map.clear()    
console.log(map) //Map(0) {}

4.查找 has() 返回 有true / 無false

console.log(map.has("dl")) //false

總結(jié):map在現(xiàn)在開發(fā)中已經(jīng)經(jīng)常使用,它的靈活性和高效性是我們喜歡的。開發(fā)中試著去使用map吧!

第15節(jié):用Proxy進(jìn)行預(yù)處理

當(dāng)我們在操作一個對象或者方法時會有幾種動作,比如:在運(yùn)行函數(shù)前初始化一些數(shù)據(jù),在改變對象值后做一些善后處理。這些都算鉤子函數(shù), Proxy的存在就可以讓我們給函數(shù)加上這樣的鉤子函數(shù),你也可以理解為在執(zhí)行方法前預(yù)處理一些代碼。你可以簡單的理解為他是函數(shù)或者對象的生命周期。

Proxy的應(yīng)用可以使函數(shù)更加強(qiáng)大,業(yè)務(wù)邏輯更加清楚,而且在編寫自己的框架或者通用組件時非常好用。Proxy涉及的內(nèi)容非常多,那這里我就帶你入門并且介紹給你后續(xù)的學(xué)習(xí)方法。

在學(xué)習(xí)新知識之前,先來回顧一下定義對象的方法。

let md = {
  lz:function(val){
    return val+100
  },
  role:'王一博'
}
console.log(md.lz(100)) //200
console.log(md.role) //王一博

聲明了一個md 對象,增加了一個對象方法lz和一個對象屬性 role,然后在控制臺進(jìn)行了打印。

聲明Proxy
我們用new的方法對Proxy進(jìn)行聲明??梢钥匆幌侣暶鱌roxy的基本形式。

new Proxy({},{});

需要注意的是這里是兩個花括號,第一個花括號就相當(dāng)于我們方法的主體,后邊的花括號就是Proxy代理處理區(qū)域,相當(dāng)于我們寫鉤子函數(shù)的地方。

現(xiàn)在把上邊的obj對象改成我們的Proxy形式。

var pro = new Proxy({
    lz:function(val){
    return val+100
  },
  role:'王一博'
}, {
  get:function(target,key,property){
    console.log('I am a dancer');
    console.log(target); // {lz: ?, role: "王一博"}
    console.log(key);// role
    return target[key];
  },
    });
console.log(pro.role);

可以在控制臺看到結(jié)果,先輸出了I am a dancer。相當(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:改變前的原始值。
let pro = new Proxy({
  lz:function(val){
    return val+100
  },
  role:'王一博'
},{
  get:function(target,key,property){
    console.log('I am a dancer');
    console.log(target); //{lz: ?, role: "王一博"}
    console.log(key);//role
    return target[key];
  },
  set:function(target,key,value,receiver){
    console.log(`setting ${key} = ${value}`) //setting role = 肖戰(zhàn)
    return target[key] = value
  }
})
console.log(pro.role) //I am a dancer 王一博
pro.role = '肖戰(zhàn)'
console.log(pro.role) //肖戰(zhàn)

apply的使用
apply的作用是調(diào)用內(nèi)部的方法,它使用在方法體是一個匿名函數(shù)時??聪逻叺拇a。

let target = function(){
  return '我是魏無羨'
}
//預(yù)處理方法
let handler = {
  apply(target,ctx,args){
    console.log('喜歡我') //喜歡我
    return Reflect.apply(...arguments)
  }
}
let pro2 = new Proxy(target,handler)
console.log(pro2()) //我是魏無羨

第16節(jié):promise對象的使用

ES6中的promise的出現(xiàn)給我們很好的解決了回調(diào)地獄的問題,在使用ES5的時候,在多層嵌套回調(diào)時,寫完的代碼層次過多,很難進(jìn)行維護(hù)和二次開發(fā),ES6認(rèn)識到了這點(diǎn)問題,現(xiàn)在promise的使用,完美解決了這個問題。那我們?nèi)绾卫斫鈖romise這個單詞在ES5中的作用那,你可以想象他是一種承諾,當(dāng)它成功時執(zhí)行一些代碼,當(dāng)它失敗時執(zhí)行一些代碼。它更符合人類的行為思考習(xí)慣,而不在是晦澀難懂的冰冷語言。

promise的基本用法
promise執(zhí)行多步操作非常好用,那我們就來模仿一個多步操作的過程,那就以吃飯為例吧。要想在家吃頓飯,是要經(jīng)過三個步驟的。

  1. 洗菜做飯。
  2. 坐下來吃飯。
  3. 收拾桌子洗碗。
    這個過程是有一定的順序的,你必須保證上一步完成,才能順利進(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ā)中使用率算是最高的,而且你面試前端都會考這個對象,大家一定要掌握好。

第17節(jié):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 cql= new Coder;
jspang.name('陳情令');

類的多方法聲明

//class類 ES6 多方法使用
class Coder {
  name(val){
    console.log(val) //陳情令
    return val //要有返回值
  }
  skill(val){
    console.log(this.name('陳情令')+':'+'Skill-'+val) //陳情令:Skill-修仙
  }
}

let cql = new Coder(1,2);
// cql.name('陳情令')
cql.skill('修仙')

這里需要注意的是兩個方法中間不要寫逗號了,還有這里的this指類本身,還有要注意return 的用法。

類的傳參
在類的參數(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('陳情令')+':'+'Skill-'+val) //陳情令:Skill-修仙
  }
  //類的參數(shù)設(shè)置
  constructor(a,b){
    this.a = a;
    this.b = b
  }
  add(){
    return this.a + this.b
  }
}

let cql = new Coder(1,2);
console.log(cql.add()) //3

我們用constructor來約定了傳遞參數(shù),然后用作了一個add方法,把參數(shù)相加。這和以前我們的傳遞方法有些不一樣,所以需要小伙伴們多注意下。

class的繼承
如果你學(xué)過java,一定知道類的一大特點(diǎn)就是繼承。ES6中也就繼承,在這里我們簡單的看看繼承的用法。

//繼承父類
class mdzs extends Coder{

}
//實(shí)例化
let wyb = new mdzs
wyb.name('王一博')

第18節(jié):模塊化操作

在ES5中我們要進(jìn)行模塊華操作需要引入第三方類庫,隨著前后端分離,前端的業(yè)務(wù)日漸復(fù)雜,ES6為我們增加了模塊話操作。模塊化操作主要包括兩個方面。

  • export :負(fù)責(zé)進(jìn)行模塊化,也是模塊的輸出。
  • import : 負(fù)責(zé)把模塊引,也是模塊的引入操作。

export的用法:

export可以讓我們把變量,函數(shù),對象進(jìn)行模塊話,提供外部調(diào)用接口,讓外部進(jìn)行引用。先來看個最簡單的例子,把一個變量模塊化。我們新建一個temp.js文件,然后在文件中輸出一個模塊變量。

export var a = 'zyl';

然后可以在index.js中以import的形式引入。

import {a} from './temp.js';
console.log(a);

這就是一個最簡單的模塊的輸出和引入。

多變量的輸出
這里聲明了3個變量,需要把這3個變量都進(jìn)行模塊化輸出,這時候我們給他們包裝成對象就可以了。

var a ='xz';
var b ='肖戰(zhàn)';
var c = '陳情';
export {a,b,c}

函數(shù)的模塊化輸出

export function add(a,b){
    return a+b;
}

as的用法
有些時候我們并不想暴露模塊里邊的變量名稱,而給模塊起一個更語義話的名稱,這時候我們就可以使用as來操作。

var a ='xz';
var b ='肖戰(zhàn)';
var c = '陳情';
export {
    x as a,
    y as b,
    z as c
}

export default的使用 加上default相當(dāng)是一個默認(rèn)的入口。在一個文件里export default只能有一個。我們來對比一下exportexport default的區(qū)別。

1.export

export var a ='xz';
 
export function add(a,b){
    return a+b;
}

對應(yīng)的導(dǎo)入方式

import {a,add} form './temp';//也可以分開寫

2.export defalut

export default var a='xz';

對應(yīng)的引入方式

import str from './temp';

ES6的模塊化不能直接在瀏覽器中預(yù)覽,必須要使用Babel進(jìn)行編譯之后正??吹浇Y(jié)果。

學(xué)習(xí)完了還是要多看書呀?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,697評論 0 1
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,908評論 0 1
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 3,119評論 3 37
  • 前面的話 ??我們經(jīng)常定義許多對象和數(shù)組,然后有組織地從中提取相關(guān)的信息片段。在ES6中添加了可以簡化這種任務(wù)的新...
    CodeMT閱讀 537評論 0 0
  • 早上起來洗漱完把思品復(fù)習(xí)題背了一部分,明早繼續(xù)背剩下的部分,快考試了,抓緊時間復(fù)習(xí)。 上午看到老師發(fā)...
    秋日私語666閱讀 241評論 0 0

友情鏈接更多精彩內(nèi)容