ES6 從入門到放棄^_^

小伙伴大多數(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

對ES6的知識點(diǎn)做了簡單的整理與應(yīng)用腿箩,詳解可以查找其他文章豪直,多練多看才能立于不敗(裝X)之地

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珠移,一起剝皮案震驚了整個濱河市弓乙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钧惧,老刑警劉巖暇韧,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浓瞪,居然都是意外死亡懈玻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門乾颁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涂乌,“玉大人,你說我怎么就攤上這事英岭⊥搴校” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵诅妹,是天一觀的道長罚勾。 經(jīng)常有香客問我,道長吭狡,這世上最難降的妖魔是什么尖殃? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮划煮,結(jié)果婚禮上送丰,老公的妹妹穿的比我還像新娘。我一直安慰自己般此,他們只是感情好蚪战,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布牵现。 她就那樣靜靜地躺著铐懊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞎疼。 梳的紋絲不亂的頭發(fā)上科乎,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音贼急,去河邊找鬼茅茂。 笑死捏萍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的空闲。 我是一名探鬼主播令杈,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼碴倾!你這毒婦竟也來了逗噩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤跌榔,失蹤者是張志新(化名)和其女友劉穎异雁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體僧须,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纲刀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了担平。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片示绊。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖暂论,靈堂內(nèi)的尸體忽然破棺而出耻台,到底是詐尸還是另有隱情,我是刑警寧澤空另,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布盆耽,位于F島的核電站,受9級特大地震影響扼菠,放射性物質(zhì)發(fā)生泄漏摄杂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一循榆、第九天 我趴在偏房一處隱蔽的房頂上張望析恢。 院中可真熱鬧,春花似錦秧饮、人聲如沸映挂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柑船。三九已至,卻和暖如春泼各,著一層夾襖步出監(jiān)牢的瞬間鞍时,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逆巍,地道東北人及塘。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像锐极,于是被迫代替她去往敵國和親笙僚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容