ES6では、次の2つの機能は非常にほぼ同一であると思われます。
function () {
return this;
}.bind(this);
() => {
return this;
};
最終的な結果は同じようです。矢印関数は、this
コンテキストが作成されたthis
と同じ値にバインドされたJavaScript関数オブジェクトを生成します。
明らかに、一般的な意味では、Function.prototype.bind
は矢印関数よりも柔軟性があります。ローカルthis
以外の値にバインドできます。また、関数のthis
をいつでもバインドできます。 。ただし、bind
自体が矢印関数とどのように異なるかを尋ねているのではなく、bind
でthis
をすぐに呼び出すことと矢印関数がどのように異なるかを尋ねています。
ES6の2つのコンストラクトに違いはありますか?
まあ、大丈夫、それは少し時期尚早です。矢印関数に固有の3つのtiny違いがあります。
矢印関数はnew
で使用できません。
これは、もちろん、それらがprototype
プロパティを持たず、古典的に着想を得た構文でオブジェクトを作成するために使用できないことを意味します。
new (() => {}) // TypeError: () => {} is not a constructor
ただし、これはおそらく最適です。new
の動作方法は、バインドされた関数ではあまり意味がありません。
矢印関数は、通常のJavaScript関数がアクセスできる特別なarguments
オブジェクトにアクセスできません。
(() => arguments)(1, 2, 3) // ReferenceError: arguments is not defined
これはおそらくもう少しの落とし穴です。おそらく、これはJavaScriptのその他の奇妙な点の1つを取り除くためです。 arguments
オブジェクトはそれ自身の特別な獣です 、そして奇妙な振る舞いを持っているので、投げられたのは驚くことではありません。
代わりに、ES6には魔法の隠し変数なしで同じことを達成できるスプラットがあります。
((...args) => args)(1, 2, 3) // [1, 2, 3]
矢印関数には独自の new.target
プロパティ、new.target
含まれる関数の存在する場合。
これは、矢印関数の「魔法のように」導入された値を削除する他の変更と一致しています。上記のように、とにかくnew
で矢印関数を使用できないことを考えると、この特定の変更は特に明白です。
それ以外の場合、矢印は意味的にバインドされた関数に似ています。追加の荷物を持ち歩く必要がなく、最初に通常の関数から変換する必要がないため、矢印のパフォーマンスが向上する可能性がありますが、動作はまったく同じです。
いくつかの違いがあります。
矢印関数は構築できません。矢印関数とバインド関数の両方に_.prototype
_プロパティがありませんが、前者はnew
で呼び出されたときに例外をスローしますが、後者はバインドされた値を無視し、ターゲット関数を新しいインスタンスのコンストラクタ(ただし、部分的に適用されたバインドされた引数)。
_function F() {}
var f = () => {},
boundF = F.bind({});
console.log(new boundF(), new boundF instanceof F) // {}, true
console.log(new f) // TypeError
_
矢印関数には、字句arguments
、_new.target
_、およびsuper
もあります(字句this
だけではありません)。矢印関数の呼び出しはこれらのいずれも初期化せず、矢印関数が定義された関数から継承されます。バインドされた関数では、ターゲット関数のそれぞれの値を参照します。
矢印関数は、実際にはthis
値をバインドしません。むしろ、それらは持っておらず、this
を使用すると、レキシカルスコープの変数名のように検索されます。これにより、this
がまだ使用可能でないときに矢印関数を遅延定義することができます。
_class X extends Object {
constructor() {
var f = () => this, // works
boundF = function(){ return this; }.bind(this);
// ^^^^ ReferenceError
super(); // initialises `this`
console.log(f(), f() == this); // {}, true
}
}
new X;
_
矢印関数をジェネレーター関数にすることはできません(ただし、ジェネレーターを返すことはできます)。ジェネレーター関数で.bind()
を使用できますが、矢印関数を使用してこれを表現する方法はありません。
もう1つ微妙な違いがあります。
=>の直後の{}中括弧を省略することにより、矢印関数は 'return'キーワードを使用せずに値を返すことができます。
var f=x=>x; console.log(f(3)); // 3
var g=x=>{x}; console.log(g(3)); // undefined
var h=function(x){x}; console.log(h(3)); // undefined
var i=x=>{a:1}; console.log(i(3)); // undefined
var j=x=>({a:1}); console.log(j(3)); // {a:1}