1. 程式人生 > >ES6中函數新增的方式方法

ES6中函數新增的方式方法

消失 bsp foo 兩個 max original 1.2 陌生 ted

緒 言

ES6

 大家對JavaScript中的函數都不陌生。今天我就為大家帶來ES6中關於函數的一些擴展方式和方法。

1.1函數形參的默認值

1.1.1基本用法

  ES6 之前,不能直接為函數的參數指定默認值,只能采用變通的方法。如下代碼:

        function func(x,y){
            y = y || "tom";
            console.log(x,y);
        }
        
        func("hello");            //hello tom
        func("hello","woeld");    //
hello woeld func("hello","");    //hello tom
        function func(x,y){
            if(typeof y === "undefined"){
                y = y || "tom";
            }
            console.log(x,y);
        }
        
        func("hello");            //hello tom
        func("hello","woeld");    //hello woeld
func("hello",""); //hello

  ES6 允許為函數的參數設置默認值,即直接寫在參數定義的後面。如下代碼:

        function func(x,y="tom"){
            console.log(x,y);
        }
        
        func("hello");            //hello tom
        func("hello","woeld");    //hello woeld
        func("hello","");        //hello

  ES6 的寫法還有兩個好處:首先,閱讀代碼的人,可以立刻意識到哪些參數是可以省略的,不用查看函數體或文檔;其次,有利於將來的代碼優化,即使未來的版本在對外接口中,徹底拿掉這個參數,也不會導致以前的代碼無法運行。

1.1.2默認值與解構賦值結合

        function func({x,y=3}){
            console.log(x,y);
        }
        
        func({});            //undefined 3
        func({x:1});        //1 3
        func({x:1,y:2});    //1 2
        func();                //Uncaught TypeError: Cannot destructure property `x` of ‘undefined‘ or ‘null‘.

  上面代碼只使用了對象的解構賦值默認值,沒有使用函數參數的默認值。只有當函數func的參數是一個對象時,變量xy才會通過解構賦值生成。如果函數func調用時沒提供參數,變量xy就不會生成,從而報錯。通過提供函數參數的默認值,就可以避免這種情況。

  如果沒有提供參數,函數func的參數默認為一個空對象。  

1.1.3參數默認值的位置
        function func(x,y=2,z){
            console.log(x,y,z);
        }
        func();                //undefined 2 undefined
        func(1);            //1 2 undefined
        func(1, ,3);        //Uncaught SyntaxError: Unexpected token
        func(1,undefined,3);//1 2 3
     func(1,null,3); //1 null 3

  上面代碼中,有默認值的參數都不是尾參數。這時,無法只省略該參數,而不省略它後面的參數,除非顯式輸入undefined

  如果傳入undefined,將觸發該參數等於默認值,null則沒有這個效果。

1.1.4函數的length屬性和作用域

length

  指定了默認值以後,函數的length屬性,將返回沒有指定默認值的參數個數。也就是說,指定了默認值後,length屬性將失真。

作用域

  一旦設置了參數的默認值,函數進行聲明初始化時,參數會形成一個單獨的作用域(context)。等到初始化結束,這個作用域就會消失。這種語法行為,在不設置參數默認值時,是不會出現的。

1.2rest參數

  ES6 引入 rest 參數(形式為...變量名),用於獲取函數的多余參數,這樣就不需要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。如下代碼:

        function add(...values) {
          var sum = 0;
        
          for (var val of values) {
            sum += val;
          }
        
          console.log(sum);
        }
        
        add(2, 5, 3) // 10

  上面代碼的add函數是一個求和函數,利用 rest 參數,可以向該函數傳入任意數目的參數。

  rest 就是一個真正的數組,數組特有的方法都可以使用

  註意,rest 參數之後不能再有其他參數(即只能是最後一個參數),否則會報錯

1.3name屬性

  函數的name屬性,返回該函數的函數名。如下代碼:

        var a = function func(){};
        console.log(a.name);    //func
        var b = function(){};
        console.log(b.name);    //b

1.4箭頭函數

基本用法與註意事項

  ES6 允許使用“箭頭”(=>)定義函數。如下代碼:

        var f = v => v;
        //上面的箭頭函數等同於
        var f = function(v) {
          return v;
        };

如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。如下代碼:

var f = () => 5;
// 等同於
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2) {
  return num1 + num2;
};

如果箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,並且使用return語句返回。如下代碼:

var sum = (num1, num2) => { return num1 + num2; }

箭頭函數可以與變量解構結合使用。如下代碼:

var full = ({ first, last }) => first + ‘ ‘ + last;

// 等同於
function full(person) {
  return person.first + ‘ ‘ + person.last;
}

箭頭函數使得表達更加簡潔。如下代碼:

var isEven = n => n % 2 == 0;
var square = n => n * n;

註意事項: 

  (1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。

  (2)不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。

  (3)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。

  (4)不可以使用yield命令,因此箭頭函數不能用作 Generator 函數。

    this對象的指向是可變的,但是在箭頭函數中,它是固定的。

1.5綁定this

  箭頭函數可以綁定this對象,大大減少了顯式綁定this對象的寫法(callapplybind)。但是,箭頭函數並不適用於所有場合,所以現在有一個提案,提出了“函數綁定”(function bind)運算符,用來取代callapplybind調用。

  函數綁定運算符是並排的兩個冒號(::),雙冒號左邊是一個對象,右邊是一個函數。該運算符會自動將左邊的對象,作為上下文環境(即this對象),綁定到右邊的函數上面。如下代碼:

foo::bar;
// 等同於
bar.bind(foo);

foo::bar(...arguments);
// 等同於
bar.apply(foo, arguments);

1.7尾調用

  尾調用(Tail Call)是函數式編程的一個重要概念,是指某個函數的最後一步是調用另一個函數。如下代碼:

function f(x){
  return g(x);
}

  尾調用不一定出現在函數尾部,只要是最後一步操作即可。下面代碼中,函數mn都屬於尾調用,因為它們都是函數f的最後一步操作。

function f(x) {
  if (x > 0) {
    return m(x)
  }
  return n(x);
}

ES6中函數新增的方式方法