向ES6看齊,用更好的JavaScript(二)


本文是ES6系列的第二篇,主要介紹ES6中對現有對象方法屬性的拓展,先上傳送門:

1 增加了模板字符串

先看一下,ES6之前我們是如何實現輸出模板的:

    document.getElementById('root').innerHTML = "the user name is " + username + "\nthe user age is  " + age;

這樣通過字符串相加拼接確實挺繁瑣的,很容易出錯,ES6引入了模板字符串來簡化代碼,兩者輸出效果是一樣:

    //ES6環境下
    document.getElementById('root').innerHTML = `the user name is ${username}
    the user age is  ${age}`;

通過反引號包裹的字符串來聲明模板字符串,插入變量直接通過${變量名}實現,另外要注意模板字符串中的所有空格和換行都是被保留的。

${變量名}中大括號內不僅支持變量名,對於任意的JavaScript表達式也是支持的,例如可以這樣用:

    var result =  `my name is ${(function(){return 'vicfeel';})()}`;

2 數組的拓展

  • Array.from( ),將偽數組對象轉換為真正的數組

什么是偽數組對象?具有數組的結構,但不是數組對象,不能使用數組方法如forEach等,舉幾個栗子:

    let fakeArr1 = {
        '0':1,
        '1':2,
        '2':3,
        'length':3
    };
    
    function f(){
        let fakeArr2 = arguments;
    }
    
    let fakeArr3 = document.querySelectorAll('div');
    
    //上面三類都是偽數組對象
    'forEach' in fakeArr1; //false
    let arr = Array.from(fakeArr1); //ES5的寫法 var arr = Array.slice.call(fakeArr1);
    'forEach' in arr;   //true
    
  • Array.find( ),在數組中檢索第一個匹配要素

find()參數為一個函數,設置查找條件,看栗子:

    let arr = [1,3,5,7];
    var result = arr.find(function(value, index, arr){
        return value > 4;
    });
    var result2 = farr.find(function(value, index, arr){
        return value > 10;
    });
    console.log(result); //5
    console.log(result2); //找不到返回undefined;

findIndex()方法與find()類似,只不過查找的是序號:

    let arr = [1,3,5,7];
    var result = arr.findIndex(function(value, index, arr){
        return value > 4;
    });
    var result2 = farr.findIndex(function(value, index, arr){
        return value > 10;
    });
    console.log(result); //2
    console.log(result2); //找不到返回-1;
  • Array.fill( ),給定一個值來填充數組
    let arr = [1,2,3];
    arr.fill(5); //[5,5,5]
    
    //fill也可以接收3個參數,第二個和第三個參數分別為填充開始的位置和結束的位置
    let arr2 = [1,2,3,4,5,6];
    arr2.fill(5,1,3); //[1,5,5,4,5,6]

3 函數增加默認參數

ES6之前的函數是無法帶有默認參數的,我們通常采用以下方式實現默認參數設置:

    function f(name,age){
        //設置默認值
        name = name || 'defaultName';  
        age = age || 'defaultAge';
    }

ES6中提供了新的方法:

    //ES6環境下
    function f(name,age = 23){
        console.log(name + ',' + age);
    }
    f('vicfeel');  //vicfeel,23

通過Babel可以將ES6代碼轉換為瀏覽器支持ES5代碼,這實際上是用ES5來模擬的一個過程,可以幫助我們了解ES6該方法的實現原理:

    //Babel轉換后
    function f(name) {
        var age = arguments.length <= 1 || arguments[1] === undefined ? 23 : arguments[1];
    
        console.log(name + ',' + age);
    }
    f('vicfeel'); //vicfeel,23

從上面可以看出,如果第二個參數嚴格等於“===”undefined就使用默認參數,這實際上在原有函數的基礎上對形參加了一層解析賦值(見上一篇中的變量解析賦值)。

4 函數新增rest參數

ES6引入了rest參數(“...變量名”),用於獲取函數的多余參數,這樣就不需要使用arguments對象了,看個栗子:

    function f(...vals){
        console.log(vals);  //[1,2,3]
    }
    
    f(1,2,3);

上例中的vals類型為Array,值為[1,2,3],可以看成將arguments轉換為數組后的結果,而且要比arguments有更高的靈活性,rest參數還可以這樣用:

    //ES6環境下
    function f(v,...vals){
        console.log(v);   //'temp'
        console.log(vals); //[1,2,3]
    }
    
    f('temp',1,2,3);
    //ES5通過arguments的模擬
    function f(v) {
        console.log(v);
    
        for (var _len = arguments.length, vals = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
            vals[_key - 1] = arguments[_key];
        }
    
        console.log(vals);
    }
    
    f('temp', 1, 2, 3);

另外在使用rest時要注意的一點,rest參數后不可以再加別的參數:

    function f(...vals,v){ }  //這種方式會報錯

除了在函數中作為rest參數,“ ... ”本身可以作為一個運算符使用,用處與rest參數剛好相反,是將一個數組轉為用逗號分隔的參數序列,看看栗子:

    function add(x,y){
       return x + y;
    }
    
    var arr = [23,12];
    add(...arr); //35
    
    Math.max(...[4, 13, 15]) // 等同於Math.max(4, 13, 15);

    //結合rest使用
    function f(...vals){
        vals //[1,2,3]
    }
    
    var arr = [1,2,3];
    f(...arr);
    //當然上面這樣用是多次一舉,轉換為參數再轉回來,目的是為了理解兩者是互為逆操作的
    
    //其它用法
    var nodeList = document.querySelectorAll('div');
    var array = [...nodeList];
    
    var arr1 = [1,2,3],arr2 = [4,5,6];
    var arr3 = [...arr1,...arr2]; //合並數組,在ES5中我們一般是這樣用的arr1.concat(arr2);

5 增加箭頭=>函數

直接用Babel轉換“var f = a => b”為ES5看了一下

    //var f = a => b;
    
    var f =function (a) {
      return b;
    };

這樣一下就明了了,我們可以將箭頭函數理解成一種語法糖,是對函數的一種簡化,a為參數,b為返回值

看一下復雜的用法:

    //當傳入多個參數或對象時,要用()包裹
    var add = (a,b) => a + b
    //等同於
    var add = function(a,b){ return a + b; }
    
    //傳入對象
    var plus = ({name,age}) => name + age;
    var person = {
        name:'Vicfeel',
        age:23
    };
    plus(person); //Vicfeel23
    

靈活運用箭頭函數,可以簡化很多操作:

    let arr1 = [1,2,3,4];
    arr1.map(x => x * x);
    
    const IsEven = x => x % 2 == 0;
    
    let arr2 = [12,2,43,3,18];
    arr2.sort((x,y) => x - y);

另外,關於使用箭頭函數有一點需要注意的地方:this對象的指向是可變的,但是在箭頭函數中,它是固定的,我們結合例子看一下:

    var handler = {
      init: function() {
        document.addEventListener('click',
          e => this.doSomething(e), false);
      },
    
      doSomething: function(e) {
        console.log('do something);
      }
    };

我們為document綁定了點擊事件,回調函數中使用箭頭函數,調用handler的doSomething方法,一般的函數在點擊執行中this會發生改變,指向document,並報錯doSomething未定義,但在箭頭函數中this在定義時便是固定的不再改變,將上面的例子轉換為ES5看一下:

    //ES5
    var handler = {
        init: function init() {
            var _this = this;
    
            document.addEventListener('click', function (e) {
                return _this.doSomething(e);
            }, false);
        },
    
        doSomething: function doSomething(e) {
            console.log('do something');
        }
    };

轉換后的ES5代碼就清楚地說明了,箭頭函數里面根本沒有自己的this,而是引用外層的this。

參考Reference
http://www.ecma-international.org/ecma-262/6.0/index.html
http://es6.ruanyifeng.com/
http://www.cnblogs.com/Wayou/p/es6_new_features.html
http://www.cnblogs.com/snandy/p/4403111.html

博文作者:vicfeel
博文出處:http://www.cnblogs.com/vicfeel
本文版權歸作者和博客園共有,歡迎轉載,但須保留此段聲明,並給出原文鏈接,謝謝合作!
如果閱讀了本文章,覺得有幫助,您可以為我的博文點擊“推薦一下”!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM