ECMAScript 6 Section 1

你們好,本人名叫蘇日儷格,你們叫我 (格格) 就好,最近我一直在研究ES6,在研究的過程當中並記錄了下來,給你們分享下,有什麼問題或者建議能夠在評論區給出,望路過的大佬們不喜勿噴,本文僅供初入ES6江湖的人士(小白)專用,下面就讓咱們來聊一聊ECMAScript:javascript

ECMAScript是一種由Ecma國際(前身爲歐洲計算機制造商協會,英文名稱是European Computer Manufacturers Association)經過ECMA-262標準化的腳本程序設計語言。這種語言在萬維網上應用普遍,它每每被稱爲JavaScriptJScript,但實際上後二者是ECMA-262標準的實現和擴展。前端

綜上所述咱們能夠把ECMAScript當成是一個標準,而實現者是:JavaScript、typescript和actionscript;若是理解不了,就能夠這麼理解,好比HTML也是一個標準,而實現者是瀏覽器;vue

小白:以前有看到過ES2015,它又是什麼意思呢?
格格:其實咱們一般所說的ES6也就是ES2015,意思就是在2015年發佈的ECMAScript 6.0版本,而以後的ES2016和ES2017也都是ES6裏面的,所以二者是同樣的,只不過ES2015是官方的名稱,java

下面讓咱們來聊一聊ES6中的新特性吧:git

1. let const

let和const都是定義(聲明)用的,let是聲明變量,而const是聲明常量的;
變量:定義完了能夠改變
常量:定義完了沒法改變github

var雖然也是聲明變量的,不過var聲明有不少潛在的問題,至因而哪些問題,讓咱們來看一個例子:web

for (var i=0; i<10; i++) {
    //coding
}
alert(i);  // i=10

小白:⊙▽⊙這不科學啊,在外面還能訪問?
格格:這個時候有的朋友看了就感受很神奇,尤爲是學Java的,不該該是這樣的對吧,但事實如此,接着往下看你就明白了typescript

若是非得說到做用域的問題的話,那麼有兩種做用域,一個是全局做用域,另外一個就是函數做用域(局部做用域),在這個例子裏面聲明的i就是一個全局的變量,因此下面是能夠訪問到的,若是下文繼續使用i的話,那麼就要從i=10開始,後果不堪設想。json

下面咱們再來看一個例子:小程序

var a = 1;
function test(){
    alert(a);  // a = undefined
    var a = 2;
}
test();

這個例子暴露了一個問題,其實也不算是問題,就是由於JavaScript具備本身的特性:變量提高的問題(也能夠叫作預解析),這究竟是個什麼東西呢?上面的例子能夠也當作是下面的例子:

var a = 1;
function test(){
    var a;
    alert(a);
    a = 2;
}
test();

相信你們已經看懂了,在代碼執行的過程當中,事先定義了一個a,這時並無賦值,a固然就是undefined;

由此咱們給出一個定義:變量提高意思就是在js執行以前,會把變量提到頂部,並且不會突破做用域;再看一下預解析的例子:

<script type="text/javascript">
    var a = 1;
</script>
<script type="text/javascript">
    alert(a);  // a = 1
</script>

JavaScript雖然是一個腳本語言,無需解析,可是它仍是有一個小小的預解析的過程:
讀取一個script標籤 ==> 預解析 ==> 執行代碼 ==> 再讀取下一個script標籤 ==> ...依次循環

下面讓咱們回到let和const:

for (let i=0; i<10; i++) {
    //coding...
}

alert(i);   // i is not defined

你們能夠看到,一樣的例子使用let定義i的話,外面調用就會報錯,那麼這又是由於什麼呢?

這就是ES6中引入的新特性:塊級做用域
塊級做用域就是{ coding... } 只要是帶有{}的都是一個塊級做用域,下面到了考察你們的時刻了:

let a = 1;
function test(){
    alert(a);
    let a = 2;
}
test();

和以前的例子同樣,只不過將var換成了let,這個時候的結果就是a is not defined,由於let只在塊級做用域中起做用,因此a不多是1,因爲let不能提高,因此a就是未定義。
綜上所述:let的第一個特性就是沒有預解析,也不存在變量提高

小白:什麼鬼?什麼叫作第一個特性,難道還有第二個特性不成◔ ‸◔?
格格:那麼我要在這裏恭喜你中了大獎了,回家準備買彩票吧,它確實有第二個特性<( ̄ˇ ̄)/

下面在讓咱們一塊兒看一個例子:

let a = 1;
let a = 2;
alert(a);

這個時候你會發現,它和var是有着很是大的區別的,正常使用var的時候你們都知道,a確定是等於2的,那麼在這裏Identifier 'a' has already been declared,這句話的意思是a已經被定義了,也就是說let不容許重複定義同一個變量

格格:這就是它的第二個特性了,接來下咱們要講的就是let的第三個特性ʅ(´◔౪◔)ʃ
小白:什麼?o( ̄ヘ ̄o#) 還有第三個?
格格:其實第三個便是第二個,第二個便是第三個つ﹏⊂

下面咱們來看一個例子:

for (let i=0; i<10; i++) {
    let i = 2;
    console.log(i);
}

小白:so easy!i已經被定義了唄
格格:嘿嘿,被忽悠了吧,答案是輸出了10個2
小白:(・∀・*) 爲啥子嘛

剛纔說到,不容許重複定義一個變量,但它的條件確定是創建在塊級做用域下的呀,這個循環中的i是做用域裏面的i的父級,因此在裏面仍是能夠定義的,第三個特性就算是給第二個加個補充:在不一樣做用域下,能夠重複定義

小白:噢噢,剛纔好像被晃了一會兒→_→
格格:ㄟ( ▔, ▔ )ㄏ

const的特性和let是如出一轍的,不一樣的就只是常量而已,即爲定義完了不能修改,不然報錯

下面又到了考察你們的時刻了:

const arr = ['aaa','bbb','ccc'];
arr.push('ddd');
console.log(arr);  // ["aaa", "bbb", "ccc", "ddd"]

小白:說好的不能修改了?你在逗我。。。
格格:哈哈,你又不懂了吧

這個arr是一個數組,便是一個對象,對象自己是存在引用的,若是想讓數組沒法修改的話,也有辦法的,能夠用Object.freeze(對象)

格格:因此呀,var就當作是你的前任,忘了吧...
小白:哪能說忘就忘,相信本身會慢慢接受現任的

2. 解構賦值

當我第一次聽到這個東西的時候,內心冒出了無數的疑問,這個名字太奇怪了,可是我想說的是解構賦值很是有用

當咱們定義多個變量的時候還要一個一個去命名和賦值,很是麻煩,若是用瞭解構賦值,像這樣:

let [a,b,c] = [1,2,3];
console.log(a,b,c);  // 1,2,3

正如你所看到的,它默認的把你右邊賦的值都解出來分配給左邊的變量,一一對應進行賦值

小白:這個看起來很好用,但是若是兩側不對稱了呢?
格格解構賦值意思就是說兩側的結構和格式都必須如出一轍,再舉個例子:

let [a,b,c] = [1,[2,3]];
console.log(a,b,c); // 1 [2, 3] undefined

兩側不一致就會致使像上面這樣的結果,解決方式就是:

let [a,[b,c]] = [1,[2,3]];
console.log(a,b,c); // 1 2 3

數組還有一種玩法就是:

let [a,b,c='暫無數據'] = [1,2];
console.log(a,b,c);  // 1 2 暫無數據

固然上面這種寫法用處不大,可是在交換兩個變量的值的時候,正常是還得找第三個變量打配合就行轉換,如今不須要了:

let a = 1;
let b = 2;
[a,b] = [b,a];
console.log(a,b);  // 2 1

以上這是數組的解構賦值,下面看一下json的解構賦值是怎樣的:

let {name,age,job} = {
    name: '蘇日儷格',
    age: 24,
    job: 'web前端開發'
}

解構賦值通常用在和後臺進行數據交互的時候,後臺數據大多都是json形式的傳遞的,數據多的時候都是json嵌套json,以致於有不少,這時就能夠用解構賦值全都解出來就能夠了,不要謝我,記住我是雷鋒~( ̄▽ ̄~)(~ ̄▽ ̄)~

let json = {
    name: '蘇日儷格',
    age: '24',
    job: 'web前端開發'
}
let {name,age,job} = json;
console.log(name,age,job);  // 蘇日儷格 24 web前端開發

還有第二種寫法:

let json = {
    name: '蘇日儷格',
    age: '24',
    job: 'web前端開發'
}
let {name:a,age:b,job:c} = json;
console.log(a,b,c);  // 蘇日儷格 24 web前端開發

從字面就可以理解,上面這種寫法只是給每個變量起了一個名字,可是若是起了名字以後,下面調用的時候裏面的參數仍是寫的之前名字,那麼就會報錯is not defined

接下來給你們講一個關於解構賦值的小小的應用:

function getPos(){
    return {
        l: 10,
        t: 20
    }
}
let {l, t} = getPos();
console.log(l,t);  // 10 20

固然解構賦值也能夠做爲參數進行傳遞,用法都是同樣的,保持一一對應便可。

講到這裏,給你們插一個小tip,在ES2017 6月發佈的版本中新增了一個小可愛:

function show(a,b,c){
    console.log(a,b,c); // 1 2 3
}
show(1,2,3,);

仔細看會發現咱們在傳值的時候,多傳了一個逗號(,),可是數據依然可以顯示出來,這個看似沒用,可是在與後臺交互的時候,每每會由於多了個逗號而致使程序報錯;不知道你們有沒有作過微信小程序,裏面有個配置文件app.json,是用來配置整個小程序全部的頁面的,當咱們想把另外一個做爲首頁訪問的話,還要特地去刪掉那個多餘的逗號,這個解決了咱們遇到的問題。

3. 字符串模板

字符串模板其實就是爲了下降字符串拼接難度而生的,在拼接一些數據量大的時候,這個可真的是讓人頭疼的要死,好比說:

let name = '蘇日儷格';
let age = 24;
let str = '個人名字叫'+name+',今年'+age+'歲';
console.log(str);  // 個人名字叫蘇日儷格,今年24歲

拼接起來很麻煩,數據多的話就容易亂,ES6提出了這個字符串模板中有一個(``)

小白:這個字符是怎麼打出來的呢?
格格:切換成英文輸入法,找到鍵盤上的數字1鍵前面的那個按鍵,記住不是小鍵盤數字1哦

使用反引號(``)拼接是這樣的:

let name = '蘇日儷格';
let age = 24;
let str = `個人名字叫${name},今年${age}歲`;
console.log(str);  // 個人名字叫蘇日儷格,今年24歲

格格:這樣看起來是否是清晰的不要不要的?

還有字符串新增的方法,好比說str.startsWith(要檢測的東西);這個通常用來檢測協議(http/https),返回布爾值;既然有以誰開頭了那麼就有以誰結尾:str.endsWith(要檢測的東西);這個通常用來檢測文件類型(jpg);重複字符串方法:str.repeat(次數);這個方法能夠將一個字符串重複輸出,通常不會用到,造假數據可能會用到吧

4. 箭頭函數

在箭頭函數以前,須要看一個例子:

function show(a=1){
    let a = 2;
    console.log(a); // Identifier 'a' has already been declared
}
show();

上面的代碼告訴咱們函數的參數默認已經被定義了,一經聲明,就不能再用let或者const進行聲明瞭,只能用var;這個有點跑題了,算是送你們的一個小tip吧,下面讓咱們一塊兒來看箭頭函數吧:

//普通函數的寫法:
function show(){
    return 1;
}
show();
//上面的函數的箭頭函數寫法:
let show = () => 1;  // 箭頭的左邊是參數右邊是返回值
console.log(show());

若是要想在函數裏面寫語句的時候,寫法是這樣的:

let show = (a=1,b=2) => {
    console.log(a,b);  // 1 2
}
show();

箭頭函數和普通函數除了寫法不一樣以外,還有三點不一樣,請看下面的例子:

let json = {
    name: '蘇日儷格',
    show: function(){
        setTimeout(function(){
            console.log(this.name); // 控制檯什麼都沒有輸出
        },1000);
    }
}
json.show();

這個例子大多都是在vue等框架下開發遇到的問題,由於this指向的是當前的函數,先要讓它指向外面的json對象,就還要在外面進行轉換,太麻煩,而箭頭函數則不一樣:

let json = {
    name: '蘇日儷格',
    show: function(){
        setTimeout(() => {
            console.log(this.name); // 蘇日儷格
        },1000);
    }
}
json.show();

綜上所述,第一個不一樣之處就是箭頭函數裏的this指向的是定義函數所在的對象,而不是運行時所在的對象

小白:那第二個不一樣之處呢?
格格:第二個就是箭頭函數裏面不能使用arguments,若是用了就是is not defined

解決辦法:就是...擴展運算符(在本章的第五小節)

let show = (...a) => {
    console.log(a);  // [1, 2, 3, 4, 5]
};
show(1,2,3,4,5);

第三個就是箭頭函數不能當作構造函數來用

let Show = ()=>{
    this.name = '蘇日儷格';
}
let a = new Show();
console.log(a.name);    // Show is not a constructor

5. 擴展運算符

... 表明着擴展運算符或Rest(剩餘)運算符
廢話很少說,直接帶你們看幾個例子:

// 當傳入的參數不肯定或者多個的時候,就能夠當作arguments來使用
function show(...a){
    console.log(a); // [14, 12, 54, 33, 22]
}
show(14,12,54,33,22);

此外擴展運算符還能夠解決數組的引用的問題:

let a = [14,12,54,33,22];
let b = a;  // 至關於copy
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22, 44]

上面這個例子說明了b是a的一個引用,也就是說兩者所在的內存是同一個,要想改變a不影響b的話,就要開闢一個新內存,解決方式:

let a = [14,12,54,33,22];
let b = [...a];
a.push(44);
console.log(a); // [14, 12, 54, 33, 22, 44]
console.log(b); // [14, 12, 54, 33, 22]

擴展運算符還能夠用來數組的排序,此排序並非什麼大小排序,而是按照每一位的首位數字進行排序的,第一位相同就看第二位,依次排列,和字典式排序類似,看下面的例子:

function orderBy(...a){
    return a.sort();
}
console.log(orderBy(51,12,7,34,3)); // [12, 3, 34, 51, 7]
let arr = ['aaa','bbb','ccc'];
let arr2 = "aabbcc";
console.log(arr);   // ["aaa", "bbb", "ccc"]
console.log(...arr);    // aaa bbb ccc
console.log(arr2);  // aabbcc
console.log(...arr2);   // a a b b c c

綜上所述,...能夠完成字符串和數組之間的轉換

小白:那個Rest運算符又是什麼呢?

請看下面的這個例子:

function show(a,...b){
    console.log(a); // 51
    console.log(b); // [12, 7, 34, 3]
}
show(51,12,7,34,3);

看完了這個例子懂了吧,就是說前面的參數一一對應,後面的那個...b就表明剩下的參數,由於是剩餘參數因此這個剩餘運算符要放在最後的位置,所以有的人又稱爲剩餘運算符

本文的全部內容均是一字一字敲上去的,但願你們閱讀完本文能夠有所收穫,由於能力有限,掌握的知識也是不夠全面,歡迎你們提出來一塊兒分享!謝謝O(∩_∩)O~

github我的主頁:https://github.com/YuFy1314
個人簡書:https://www.jianshu.com/u/72f239ec5d03
Resume:https://yufy1314.github.io/
等一下( •́ .̫ •̀ ),我還有最後一句話:
這裏雖然沒有都市的繁華,
也沒有山林的鳥語花香,
只有一片如水的寧靜,
古人云:
既來之則安之,
既然來到了這裏,
就能夠靜心休憩你的靈魂,
調養你疲憊的心,
再見...

相關文章
相關標籤/搜索