関数の拡張

5087 ワード

この文章は主に関数の拡張を紹介して、関数の拡張は3つの方面があります:
  • パラメータのデフォルト値
  • 矢印関数
  • テールコールの最適化
  • について
    1:パラメータのデフォルト値(個別の役割ドメインが形成されます)
    関数を直接定義するときに、undefinedが伝わっていないか、間違っている場合はパラメータを定義できます.
    //       
    //  1:
    function log(x, y = 'World') {
        console.log(x, y);
    }
    
    log('Hello');
    //Hello World
    
    log('Hello', 'China');
    /* Hello China */
    
    log('Hello', '');
    /* Hello */
    
                    。
    //  2:
    function week({ x, y = 5 }) {
        console.log(x, y);
    }
    
    week({});
    /* undefined 5 */
    
    week({x: 1});
    /* 1 5 */
    
    week({x: 1, y: 2});
    /* 1 2 */
    
    week();
    /* TypeError: Cannot read property 'x' of undefined */
    
    //  3:
    function week({x, y = 5} = {}) {
        console.log(x, y);
    }
    
    week();
    /* undefined 5 */

    パラメータのデフォルト値とデフォルト値を解く上で注意しなければならない点:
  • パラメータの変数はデフォルトで宣言されており、letまたはconstで
     function week(x = 5) {
         let x = 1;
         const x = 2;
     }
     /* SyntaxError: Identifier 'x' has already been declared */
  • を再宣言することはできません.
  • 関数は同じ名前のパラメータを持つことはできません.パラメータの変数はデフォルトで宣言されているため、
     function week(x, x, y = 1) {
         /* ... */
     }
     /* SyntaxError: Duplicate parameter name not allowed in this context */
  • を再宣言することはできません.
  • パラメータのデフォルト値は不活性評価です.この関数を実際に演算すると、デフォルトのパラメータ
     let x = 99;
     function week(p = x + 1) {
         console.log(p);
     }
     
     week();
     /* 100 */
     
     x = 100;
     week();
     /* 101 */
  • を処理します.
  • パラメータのデフォルト値は、一般に、関数length属性、すなわち関数のnameおよびletのような末尾に使用され、デフォルト値が指定されていないパラメータの個数
     (function (a) {}).length;
     //1
     
     (function (a = 5) {}).length;
     //0
     
     (function (a, b, c = 5) {}).length;
     //2
     
     (function (a = 0, b, c) {}).length;
     //0
     
     (function (a, b = 1, c) {}).length;
     //1
     
     (function(...args) {}).length;
     //0
  • を返す.
  • はパラメータのデフォルト値を設定し、パラメータは個別の役割ドメイン
     var x = 1;
     function f(x, y = x) {
         console.log(y);
     }
     
     f(2);
     //2
     
     let x = 1;
     function f(y = x) {
         let x = 2;
         console.log(y);
     }
     
     f();
     //1
  • を形成する.
    2:restパラメータです.パラメータは1つしかありません.一部のシーンではargumentの代わりにargumentのように使用できます.
    例えば、関数のargumentは関数のパラメータであることを知っています.argumentは実際には公式に推奨されていない使い方です.
      function add(...values) {
      let sum = 0;
      
      for (var val of values) {
          sum += val;
      }
      
      return sum;
      }
      
      add(2, 5, 3);
      /* 10 */
      
      function sortNumbers() {
          return Array.prototype.slice.call(arguments).sort();
      }
      
      const sortNumbers = (...numbers) => numbers.sort();

    3:厳格モード、厳格モードでは、デフォルト値、解構賦値、または拡張は厳格モードを使用できません.
    4:nameは関数名を返します
    function week() {}
    
    week.name;
    
    // "week" *
    
    var f = function () {};
    
    f.name // ""
    
    // ES6
    
    f.name // "f"

    5:矢印関数
    矢印関数の主な2点は、最初の点でthisが定義した役割ドメインを指し、2番目の点では役割ドメインの昇格がありません.
    //      
    var f = v => v;
    var f = function (v) {
        return v;
    };
    
    //      
    var sum = (num1, num2) => num1 + num2;
    var sum = function(num1, num2) {
        return num1 + num2;
    };
       
    // return,     ,         return
    //                        return。
    //               ,  return                    
    var sum = (num1, num2) => { return num1 + num2; }
    
    // 1     
    let getTempItem = id => { id: id, name: "Temp" };
    // 2 Unexpected token :
    let getTempItem = id => ({ id: id, name: "Temp" });
    
    //     
    const full = ({ first, last }) => first + ' ' + last;
    
    // rest
    const numbers = (...nums) => nums;
    numbers(1, 2, 3, 4, 5);
    // [1,2,3,4,5] 

    矢印関数で使用する注意点:
  • 関数内のthisオブジェクトは、使用時のオブジェクト
     function week() {
         setTimeout(() => {
             console.log('id:', this.id);
         }, 100);
     }
     //    id(      id)
     var id = 21;
     //  ,   this  
     week.call({ id: 42 });
     // 42
     
     function week() {
         return () => {
             return () => {
                 return () => {
                     console.log('id:', this.id);
                 };
             };
         };
     }
     //    id=1,        ,     t1,t2,t3       1
     var f = week.call({id: 1});
     
     var t1 = f.call({id: 2})()();
     var t2 = f().call({id: 3})();
     var t3 = f()().call({id: 4});
     // 1 
     
     //          
     const cat = {
         lives: 9,
         jumps: () => {
             this.lives--;
         }
     }
  • ではなく、定義時のオブジェクトを指す.
  • は、定義時にグローバルな
  • であるため、構造関数として使用できません.
  • argumentオブジェクトは使用できません.これは、
  • の代わりにrestを使用する必要があるという規定です.
  • yieldコマンド
  • は使用できません.
    6:末尾コール
    一般に厳格モードに用いられる.すなわち、厳格モードの下で、ES 6はテールコールの最適化を行った.ただし、非厳格モードではテールコールも使用できますが、最適化されていません.
    テールコールの基本概念:最後のステップは別の関数を呼び出し、外部変数に適用されない場合は内層関数の呼び出しフレームのみを保持します(外部の変数はreturnという関数に保存すべきではありません.つまり、返されるreturnはこの役割ドメインを使用しません).
    function f(x){
        return g(x);
    }

    7:末尾再帰(呼び出しスタックのスタックがある)
    function factorial(n) {
        if (n === 1) return 1;
        return n * factorial(n - 1);
    }
    
    factorial(5);
    
    //    
    function factorial(n, total) {
        if (n === 1) return total;
        return factorial(n - 1, n * total);
    }
    
    factorial(5, 1)

    8:関数パラメータの末尾カンマ、コードバージョン管理が便利
    func(
        'week',
        'month',
    );