ES6語法(二) 函數

ES6帶來最重要的變化之一就是函數的許多新特性,廢話很少說,咱們直接從最重要的變化開始提及。數組

箭頭函數

ES6此次變化中最使人興奮的就是引入了箭頭(arrow)函數,js的開發者們已經等了過久了,以前的使用中,老是會被各類bind搞得暈頭轉向。如今有了箭頭函數,這些煩惱將不復存在。瀏覽器

基本語法

(params)=>{doSomething}安全

上面的形式使比較完整的。分爲了函數參數、箭頭、函數體幾個部分。bash

若無函數參數,可使用下面的形式:
=>{doSomething}app

如果函數體只有一句的話,甚至能夠省略包含函數體的大括號。函數

=> return a;ui

箭頭函數的this值:

在ES6以前,咱們要是使用回調函數傳參就要綁定函數的對象,不然會出錯。例:this

//若是綁定,函數將沒有執行環境
    document.getElementsByName('button').onClick(this.callBack.bind(this));

    function callBack(){ do somthing }
複製代碼

而如今有了箭頭函數,那這一切將變得垂手可得。spa

document.getElementsByName('button'.onClick(()=>{
        do something...
    }));

複製代碼

這是由於箭頭函數的this值直接綁定了外部函數的this值,而且這個this值是沒法被改變的,雖然你可使用箭頭函數調用call、apply、bind方法,可是他們依然沒法改變函數的this綁定。這也是箭頭函數最重要的特性之一,不須要咱們頻繁的手動綁定函數的執行對象了。code

箭頭函數的參數。

首先要說的一點是箭頭函數沒有arguments對象。可是能夠訪問外部函數的arguments對象。舉個例子

function createArrowFunction(){
        return ()=> arguments[0];
    }
    
    let test = createArrowFunction(1,2,3,4,5);
    
    console.log(test);          // 1

複製代碼

其實也很好理解,既然箭頭函數的this直接綁定了外部函數的this,那他就應該能夠訪問到外部函數的arguments對象。

箭頭函數的參數一樣支持傳遞默認參數(詳細的會在後面講)。咱們先來看看如何使用。

let sum = (param1 = 1, param2 = 1)=>{
        console.log(param1 + param2);
    }
    
    sum();                      // 2
複製代碼
箭頭函數的應用

咱們上面也看到了一些箭頭函數的特性,首先咱們來總結一下箭頭函數的特色。

  • 語法簡潔
  • 使用方便,無需設置this綁定,支持默認參數等特性

上面的特色致使了咱們與數組搭配在一塊兒使用會相得益彰。

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

複製代碼

能夠說箭頭函數是ES6中函數部分變化最大的改變。下面咱們將瞭解一下ES6中函數的其餘變化。

函數的默認參數(函數形參的默認值)

在ES6以前咱們沒法給函數形參添加默認值,可是咱們會用另外的形式去模擬這種行爲。

function Person(name,age,sex){
        this.name = name;
        this.age = age || 18;
        this.sex = sex || female;
    }
    
    // name: Nero, age:20, sex:female
    new Person("Nero",20,female); 
    // name:Geodfrey,age:18,sex:female
    new Person("Grodfrey");
複製代碼

在上面的例子中咱們若是給函數的某個參數傳遞參數,那麼將使用傳遞的參數,不然將使用 「||」後面的內容,這樣就模擬了函數的默認參數。 上面的作法是一種很安全的作法,而且大多數JavaScript庫與開發者們都採用這種方式,可是ES6依然添加進來了新的方式,爲的是咱們更加方便的使用這種基礎操做。

基礎語法
function Person(name,age = 20,sex = female){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    
    // name:"Grodfrey", age:20, sex:female
    new Person("Grodfrey");

複製代碼

其實很簡單,就是才定義形參時加一個 「=」,後面跟上內容,簡簡單單的。還有一個比較重要的事情是,默認參數並非只支持傳遞原始值,也能夠傳遞非原始值。例如函數表達式。這個傳遞什麼類型的原始值取決於你的實際狀況。

還有一個比較重要的特色就是,若是你主動傳入undefined,函數也會調用默認值。

默認參數的臨時死區

函數的默認參數也有臨時死區,其實很容易理解,就是擁有默認值的參數不能在定義以前使用。咱們來看個例子就行了。

function sun(param1 = param2,param2 = 1){
            return param1 + param2;
    }
    
    sum(1,2);         // 2
    sum(undefined,1); //拋出錯誤
複製代碼

若是像下面的用法同樣就會報錯,簡單的來講就是在第一個參數要使用默認值(第二個參數)初始化時,可是第二個參數卻尚未被初始化,這就產生了錯誤。

元屬性(new.target)

在ES6中爲函數新增了元屬性,其實這個屬性就是爲了讓咱們區分函數的調用方式,若是使用new操做符調用函數時,元屬性就會被賦值爲new操做法的目標對象。若是是經過其餘方式調用的,那這個屬性的值就爲undefined。

function Person(name){
        if(new.target !== "undefined"){
            this.name = name;
        }else{
            console.log("請使用new操做符");
        }
    }
    
    let person = new Person("nero");
    Person.call(person,"Grodfery");     //請使用new操做符
複製代碼

這樣的化咱們就能夠明確劃分函數的做用了。一些構造函數能夠防止被其餘類型的對象調用,產生一些錯誤。

new.target屬性只能在函數內部使用,若是在函數外部使用,將會拋出錯誤。

塊級函數

在ES6中引入了塊級函數,此次是官方引入的,雖然以前有一些瀏覽器也都是實現了塊級函數,可是各不相同,此次ES6規定了塊級函數的語法。

塊級函數的語法很簡單,其實你徹底能夠看成一個let定義的變量來使用,惟一的一個區別就是:塊級函數會進行變量提高。

if(true){
        
        console.log(typeOf doSomething);    // Function
        
        function doSomething(){}
        
    }
    
    console.log(typeof doSomething);        // undefined
複製代碼

當塊級函數一旦離開相應的代碼塊,那麼這個函數將被刪除。

不定參數與展開運算符

不定參數是運行你傳入數量不定的參數進入函數,在函數中會被整合成數組。 而展開運算符與之相反,是將一個數組打散,一個一個的傳入數組。

不定參數的基本用法
function Person(name,age,sex,...others){
        this.name = name;
        this.age = age;
        this.sex = sex;
        
        for(let i = 0;i<others.length;i++){
            console.log(others[i]);
        }
    }
複製代碼

咱們能夠在傳入固定參數以後傳入任意多個參數。,都會被存儲在函數內部的不定參數同名的數組中。

不定參數的限制

不定參數有兩個須要注意的地方

  1. 不定參數只能定義在函數參數列表的末尾。
//這種使用方式是有錯誤的。
    // Uncaught SyntaxError: Rest parameter must be last formal parameter
    function doSomething(param1,...objs,param2){}
複製代碼
  1. 不定參數不能用於對象字面量setter中。
//這種操做也是不容許的,
    let obj = {
        set name(..key){}
    }
複製代碼
不定參數與arguments對象

不定參數中的值也會在arguments中,也就是說,即便不實用不定參數,繼續使用原來的arguments對象也是徹底沒問題的。

展開運算符的基本用法

展開運算符的用法就比較簡單了。

let value = [1,2,3,4,5,6,7,8,9];
    
    console.log(Math.max(...value));
複製代碼

展開運算符極大的方便了咱們,咱們不須要再寫一個循環或者經過其餘方式將一個數組的變量傳遞到函數中去,只須要在數組前面使用 「...」符號,那麼就會將他們打散傳遞給函數。

此次探討的是ES6中有關函數的變更,有些內容我省略掉了,例如name屬性,我只列舉了一些我以爲會比較經常使用的。這都是基於我在工做中的認識,若是您有一些更好的想法或者是本篇文章某處錯誤,你均可以在下面留言給我!!!

相關文章
相關標籤/搜索