1. ホーム
  2. javascript

[解決済み] アロー関数」と「ファンクション」は同じものですか?

2022-03-14 10:47:37

質問

ES2015 のアロー関数は、より簡潔な構文を提供します。

  • 今までの関数宣言や式をすべてアロー関数に置き換えることはできますか?
  • 注意することはありますか?

例を挙げます。

コンストラクタ機能

function User(name) {
  this.name = name;
}

// vs

const User = name => {
  this.name = name;
};

プロトタイプメソッド

User.prototype.getName = function() {
  return this.name;
};

// vs

User.prototype.getName = () => this.name;

オブジェクト(リテラル)メソッド

const obj = {
  getName: function() {
    // ...
  }
};

// vs

const obj = {
  getName: () => {
    // ...
  }
};

コールバック

setTimeout(function() {
  // ...
}, 500);

// vs

setTimeout(() => {
  // ...
}, 500);

可変個体関数

function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// vs
const sum = (...args) => {
  // ...
};

解決方法は?

tl;dr: ダメだ! アロー関数と関数宣言・式は等価ではないので、やみくもに置き換えることはできません。
置き換えたい関数が ではない 使用 this , arguments で呼び出されることはありません。 new であれば、イエスです。


よくあることですが 場合による . アロー関数は、関数宣言/式とは動作が異なるので、まずその違いを見てみましょう。

1. レキシカル thisarguments

アロー関数には this または arguments バインディングを使用します。その代わり、これらの識別子は他の変数と同様にレキシカルスコープで解決されます。つまり、アロー関数の内部で thisarguments の値を参照しています。 thisarguments 環境では、矢印の関数は 定義済み の中にある(つまり、arrow関数の外側にある)。

// Example using a function expression
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: function() {
      console.log('Inside `bar`:', this.foo);
    },
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: () => console.log('Inside `bar`:', this.foo),
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

関数式の場合 this の中に作られたオブジェクトを指します。 createObject . 矢印関数の場合 thisthiscreateObject そのものである。

このため、アロー関数は this を、現在の環境の

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

備考 であることも意味します。 ではなく アロー関数の this.bind または .call .

にあまり馴染みがない場合は this を読んでみてください。

2. アロー関数は new

ES2015 では、以下のような関数を区別しています。 コール である関数と コンストラクト が可能です。関数が構築可能な場合、その関数を呼び出すには new すなわち new User() . 関数が呼び出し可能である場合、その関数は new (つまり、通常の関数呼び出し)。

関数宣言/式で作成された関数は、コンストラクタブルとコールの両方が可能です。
アロー関数(およびメソッド)は呼び出しのみ可能です。 class コンストラクタはコンストラクタブルのみです。

呼び出し可能でない関数を呼び出そうとしたり、構成可能でない関数を構成しようとすると、ランタイムエラーが発生します。


これを知ると、次のように述べることができる。

交換可能です。

  • を使用しない関数 this または arguments .
  • で使用される関数 .bind(this)

ない 交換可能です。

  • コンストラクタ機能
  • プロトタイプに追加される関数/メソッド(通常、プロトタイプは this )
  • 可変個体関数(もし、それらが arguments (下記参照)
  • ジェネレーター機能。 function* 表記法

では、この例をもとに詳しく見ていきましょう。

コンストラクタ機能

アロー関数が new . 関数宣言/式を使用し続けるか class .

プロトタイプメソッド

なぜなら、プロトタイプメソッドは通常 this を使用してインスタンスにアクセスします。もし this であれば、それを置き換えることができます。しかし、簡潔な構文にこだわるのであれば class という簡潔なメソッド構文があります。

class User {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

オブジェクトメソッド

オブジェクト・リテラル内のメソッドについても同様です。メソッドがオブジェクト自体を参照する場合は this 関数式を使い続けるか、新しいメソッド構文を使用してください。

const obj = {
  getName() {
    // ...
  },
};

コールバック

それは場合による の外側をエイリアシングしている場合は、絶対に置き換えるべきです。 this を使用しているか .bind(this) :

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

しかし コールバックを呼び出すコードで、明示的に this を特定の値に設定することは、イベントハンドラ、特に jQuery でよくあることで、コールバックが this (または arguments ) の場合、あなたは できない 矢印関数を使用します。

可変個体関数

アロー関数には独自の arguments であるため、単純にアロー関数に置き換えることはできません。しかし、ES2015では、アロー関数に置き換えるための方法として arguments を使用します。 リストパラメータ .

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};


関連する質問

さらなるリソース