ES6學習手稿之基本類型擴展

前言

ES6標準以及頒佈兩年了,可是,好像尚未徹底走進咱們的平常開發。這篇文章從ES6的基本類型擴展入手,逐步展開對ES6的介紹。編程

ECMAScript和JavaScript

JavaScript是由Netscape創造的,該公司1996年11月將JavaScript語言提交國際標準化組織ECMA。因而ECMA次年就發佈了ECMAScript 1.0版本。之因此不採用JavaScript命名,緣由有兩個,一個是版權問題,另外一個也是想經過ECMAScript代表制定者是ECMA而非Netscape。固然,這不是咱們關注的重點。數組

1998年,發佈了ECMAScript 2.0,1999年發佈了ECMAScript 3.0。這是ECMAScript自頒佈以來最廣爲支持的版本,咱們如今所使用的JavaScript語法和規定大部分都來源於這個版本。它是一個通用標準,奠基了JavaScript的基本語法。2000年後,4.0開始提上日程,可是因爲各方分歧很大,致使4.0草案流產,只在最後發佈了一個小的改進版本,即ES 3.1,不久後改名爲ECMAScript 5.0。函數

2011年,ECMAScript 5.1版發佈後,就開始制定6.0版了。2015年6月發佈了ES6的第一個版本,正式名稱就是《ECMAScript 2015標準》(簡稱 ES2015)。2016年6月,小幅修訂的《ECMAScript 2016標準》(簡稱 ES2016)如期發佈,這個版本能夠看做是 ES6.1 版,由於二者的差別很是小,基本上是同一個標準。根據計劃,2017年6月發佈 ES2017 標準。所以,ES6 既是一個歷史名詞,也是一個泛指,含義是5.1版之後的 JavaScript 的下一代標準,涵蓋了ES201五、ES201六、ES2017等等,而ES2015 則是正式名稱,特指該年發佈的正式版本的語言標準。編碼

let和const

變量提高

在ES6以前,JavaScript的做用域只有兩種:全局做用域和函數做用域。而在這兩個做用域裏,存在一種奇怪的現象--變量提高。MDN上的介紹是 在編譯階段將變量和函數聲明放入內存中,但仍然保留在編碼中鍵入的位置。rest

function(){
        console.log(a);
        var a= 'hello';
    }


    function(){
        var a = undefined;
        console.log(a);
        a= 'hello';
    }

上面的兩段代碼是等價的,也說明了變量提高的本質。在函數做用域內,函數或者變量的聲明會被放到做用域頂部,而其餘操做仍然保留在原來的鍵入位置。code

塊級做用域

ES6中引入塊級做用域的概念,和Java或者C語言中的局部變量做用域很像。所以,ES6中的塊級做用域存在如下特色:暫時性死區、不可重複命名、不存在變量提高。經過關鍵字let和const聲明的變量只在塊級做用域內有效。對象

{
        let i = 1;
    }
    console.log(i);//Error

上面的代碼塊解釋了ES6中的塊級做用域的概念,一個{}即爲一個塊級做用域,做用域內的變量在做用域外沒法被訪問。ip

暫時性死區

塊級做用域首先帶來的問題就是暫時性死區。從做用域開始到變量被聲明以前的空間內是該變量的死區,在這個空間內不能對該變量進行任何操做。例如:內存

{
        //死區開始
        i = 2;//Error
        console.log(i);//Error            
        let i = 1;//死區結束
    }

不可重複命名

這個很容易理解,var聲明的變量能夠重複命名,後來的命名能夠把以前的覆蓋掉,可是let聲明的變量若是出現重複命名的狀況,會直接報錯。作用域

const

const用來聲明常量,一旦聲明,值就不可改變。所以,const一旦聲明,就必須當即初始化。這一點和Java或者C語言很像。

可是對於複合型變量,變量名不是指向數據,而是指向數據所在的地址。所以,const定義的複合型變量,只能保證變量名指向的地址不變,並不能確保改地址的內存儲的數據不變。

const foo = {};
    foo.a = 1;

    foo = {}//Error

    const b = [];
    b.length = 1;
    b = [];//Error

上面的一段代碼中,分別用const聲明瞭一個對象和一個數組。咱們能夠給對象或者數組的一個屬性賦值,可是不能直接給對象或者數組總體賦值。

變量的解構賦值

數組的解構賦值

結構賦值是ES6引入的一種新的變量賦值方式, MDN上的解釋是:解構賦值語法是一個Javascript表達式,這使得能夠將值從數組或屬性從對象提取到不一樣的變量中。

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

    let [foo, [[bar], baz]] = [1, [[2], 3]];
    console.log(foo, bar, baz);//1 2 3

上面的代碼是兩種數組解構賦值,只要等號左邊的變量在右邊的數組中可以找到對應的位置,就能夠進行解構賦值。

對象的解構賦值

對象的結構賦值和數組略有不一樣。let { key:name } = obj。等價於 let name = obj[key]。

let obj = { first: 'hello', second: 'world' };
let { first: f, second: s } = obj;
console.log(f, s);//hello world
console.log(first, second);//Error

let { foo, bar } = { foo: "aaa", bar: "bbb" };
console.log(foo, bar);// aaa bbb

let { bar, foo } = { foo: "aaa", bar: "bbb" };
console.log(foo, bar);// aaa bbb

後兩段代碼是對象屬性名和值相同時的簡潔寫法。從後兩段代碼咱們能夠了解到對象解構賦值的本質:先在對象內部找到和變量名相同的屬性,而後再把屬性值賦給變量。對象的解構賦值自己是一次變量賦值運算。

解構賦值也能夠設置默認值,當結構失敗時,直接取默認值。例如:

var {x = 3} = {};
    console.log(x); //3

    var {x, y = 5} = {x: 1};
    console.log(x, y) // 1 5

解構賦值的用處

  • 用做變量交換。 [x, y] = [y, x];
  • 函數返回多個值。 [x, y] = func();
  • 對象的快速賦值。 let a={x:1,y:2,z:3,w:4}; let {x,y}=a; let b={x,y};
  • 導入模塊的部分功能。 import {getOS} from '../utils';
  • 函數的解構參數(函數的擴展裏詳解)

函數的擴展

函數參數默認值

ES6中爲函數加入了添加默認值的功能。

function log(x, y = 'World') {
    console.log(x, y);
    }

    log('Hello');//Hello World

下邊的代碼有點意思,是函數解構參數的默認值寫法。

// 寫法一
    function m1({x = 0, y = 0} = {}) {
        return [x, y];
    }

    // 寫法二
    function m2({x, y} = { x: 0, y: 0 }) {
        return [x, y];
    }


    m1({x: 3});
    m2({x: 3});

兩種寫法略有不一樣,所表達的意思也不同。首先,函數的解構參數的寫法是這樣的:

function add({x, y}){
        return x + y;
    }

固然,這裏也能夠是數組解構,上面的代碼拿對象解構作事例。

寫法一,兩個大括號相等,表達的意思是函數參數擁有默認值,當m1函數被調用時沒有傳遞參數時,區默認值即{}。以後,進行解構賦值。方法一里的解構賦值是帶有默認值的解構賦值,所以,當解構失敗時,x和y分別取默認值0。因此m1({x: 3})的執行結果是[3,0]。

寫法二,兩個大括號相等,一樣表達的意思是函數參數擁有默認值,當m2函數被調用時沒有傳遞參數時,區默認值即{ x: 0, y: 0}。方法二里的解構賦值沒有默認值,所以,當解構失敗時,x和y的值都是undefined。因此,m2()的值是[0,0],可是m2({x: 3})的則是[3,undefined]。

函數的解構參數最大的意義在於,我能夠不用關心傳遞過來的數組或者對象內部的解構,只要內部有我想要的屬性值就夠了,這樣在必定程度上下降了邏輯函數之間的耦合。例如:

let obj = {
    name: 'hello',
    age: 18,
    address: 'BeiJing',
    mobile: '123123123',
    timestamp: '1496940548319'
}

function getName({name}){
    return name;
}

getName(obj);

rest參數

ES6爲函數參數引入rest寫法。也就是咱們偶爾會在ES6代碼裏見到的 ...

function add(...values) {
        let sum = 0;

        for (let val of values) {
            sum += val;
        }

        return sum;
    }

rest參數用於獲取函數的多餘參數,相似於arguments對象。與之不一樣的是,rest參數是一個數組,也就意味着咱們能夠對rest參數使用數組的全部方法。

箭頭函數

ES6的函數擴展裏,最引人注意的應該就是箭頭函數了。一個最簡單的箭頭函數:let f = v => v 等價於

let f = function(v){
        return v
    }

當箭頭函數沒有參數或者有多個參數時,使用圓括號把參數括起來。當箭頭函數的函數體多於一行代碼時,就採用花括號把函數體括起來,並使用return語句返回值。

箭頭函數的出現,主要是爲了簡化函數的書寫。對於開發而言,最大的好處是簡單易讀,同時匿名函數寫起來也更加舒服天然。

結語

ES6的基本擴展還有一些沒有在這裏詳細介紹。整體感受,ES6作了一些語法的豐富,使得JavaScript寫起來更加舒服了,特別是結構賦值和箭頭函數的引入,用習慣了之後,徹底是另一種編程體驗。

相關文章
相關標籤/搜索