JavaScriptのECMAScript 6新特性の_03_矢印関数(Arow Function)


もっと読む
一、概要
矢印関数(Arow Function)は、ES 6(ECMAScript 2015)における新しい文法的特性である.
関数式の簡単な形式で、オブジェクト指向の関数式プログラミングにとても適しています.
しかし、多くの制限と欠点があります.例えば、自分のthisオブジェクトがなく、argmentsパラメータがなく、prototype属性がないので、構築関数としては使えません.
一つ一つ紹介します.
二、文法
1、一般的な書き方

(param1, param2, …, paramN) => { statements } 
2、パラメータの略記
      パラメータが一つしかない場合は、括弧を省略することができます.
      パラメータがないと省略できません.

//      
singleParam => { statements }

//    
() => { statements }
3、関数の略字
      statements表現が一つしかない場合は、後の括弧を省略することができます.
      この場合は、表式を返すのと同じです.

//           ,         { }
(param1, param2, …, paramN) => expression

//    :
(param1, param2, …, paramN) => { return expression; }


//   :    :
(param1, param2, …, paramN) => { expression }
//       ,       !!!
//
      しかし、式がJSONオブジェクトの場合は、小さい括弧で拡大する必要があります.

(param1, param2, …, paramN) => ({name:"John", age:18})
      本小節の総合例:

var arr = [1, 4, 9, 16];
//
var mapedArr1 = arr.map( x => x*2 );
var mapedArr2 = arr.map( x => { x*2 } );
var mapedArr3 = arr.map( x => { return x*2 } );

console.log(mapedArr1); 
//> Array [2, 8, 18, 32]
console.log(mapedArr2);
//> Array [undefined, undefined, undefined, undefined]
console.log(mapedArr3);
//> Array [2, 8, 18, 32]
      つまり、関数体に括弧を付けます.
4、マルチパラメータ対応とパラメータ設定のデフォルト値

//     ...rest
(param1, param2, ...rest) => { statements } 

//      
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
    statements 
} 
5、リスト構造パラメータ解析のサポート

var arr = [1, 2];

var f = ([a, b] = arr, {x: c} = {x: a + b}) => a + b + c; 

f(); // 6
    同様に、パラメータがJSONオブジェクトの場合は、小さい括弧で拡大する必要があります.

//        
var f = ({length}) => length; 

//      :{length}     {length: ""}
6、書き方:改行しない
    パラメータと矢印を二行に書かないでください.同じ行に書く必要があります.

//   
var func = ()
           => 1; 
// SyntaxError: expected expression, got '=>'
総合例を以下に示す.

//
//      ,     materials     [8, 6, 7, 9]    。

var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];

// 1.   
console.log(
    materials.map(function(material) { 
      return material.length; 
    })
);

// 2.     
console.log(
    materials.map((material) => {
      return material.length;
    })
);

// 3.        
console.log(
    materials.map(material => material.length)
);


// 4.    +              
console.log(
   //               :{ length: '' }
    materials.map(({length}) => length)
); 

//
三、矢印関数は自分のthisオブジェクトがありません.
矢印関数が現れる前にnewから出た関数オブジェクトには、オブジェクト自体を指すthis属性があります.
しかし、矢印関数には、thisオブジェクトがありません.したがって、外部層thisが書き換えられたり、自身がthisで覆われたりする問題は存在しない.
1、外層thisがないと書き換えられます.
【間違い】一般的な書き方:外層thisはwindowに取って代わられます.

function Person() {
    this.age = 0;
    setInterval(function growUp() { 
        if(this.age) this.age++; 
        console.log(this === window); // true
        console.log(this.age === undefined); // true
    }, 1000);
}

var p = new Person();

//       window     setInterval   ,
//    this    window
/*
       ,window   setInterval             :
   window.setInterval = function(func, time){
         this.invoke = func;
         //...
   }
         function         window        。
        ,     this      window   。
*/
【正しい】書き方:thatを借りる.

function Person() {
    var that = this;
    that.age = 0;

    setInterval(function growUp() {
        that.age++;
        console.log(that.age);
    }, 1000);
}
var p = new Person();
【正しい】矢印関数:外側の層のthisがうまく伝達されました.

function Person(){
    this.age = 0;
    setInterval(() => {
        this.age++; 
        console.log(this.age);
    }, 1000);
}

var p = new Person();
2、自分のthisがカバーされていない問題
    callまたはapply関数を呼び出すと、矢印関数にthisオブジェクトを指定できません.

var adder = {
  base: 1,

  add: function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base: 2
    };
    //   b    this     ,      。
    return f.call(b, a);
  }
};

console.log(adder.add(1));         //   :2
console.log(adder.addThruCall(1)); //   :    2
四、矢印関数にはargmentsオブジェクトがありません. 
矢印関数には暗黙的なargments配列オブジェクトがありません.

//    :
var arguments = [3, 2, 1];
var arr = () => arguments[0];
arr(); // 3

//    :
function foo(n) {
  //     arguments     foo    ,
  //    f      。     。
  var f = () => arguments[0] + n; 
  return f();
}
foo(2); // 4
五、矢印関数にはプロトタイプの属性がありません. 

var Foo = () => {};
console.log(Foo.prototype); // undefined
六、矢印関数はnewキーワードを使用できません. 

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
七、矢印関数は単独ではyieldキーワードを使用できません. 
直接矢印関数では、他の関数に組み込まれていない限り、yieldキーを使用することはできません.
矢印関数は直接Generatorとしては使えません.
八、論理演算では、矢印関数を括弧で囲む必要があります.

let callback;

callback = callback || function() {}; // ok

callback = callback || (() => {});    // ok

callback = callback || () => {};      
// SyntaxError: invalid arrow-function arguments
参照:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
転載は明記してください
原文の出所:http://lixh1986.iteye.com/blog/2409009
を選択します.