ホームページ > 記事 > ウェブフロントエンド > es6のアロー関数と通常の関数の違いは何ですか
違い: 1. アロー関数の定義は、通常の関数の定義よりもはるかに単純、明確、高速です; 2. アロー関数は独自の this を作成しませんが、通常の関数は作成します; 3.アロー関数はコンストラクタとして使用できません アロー関数はコンストラクタとして使用できます; 4. アロー関数には独自の引数がありませんが、アロー関数には引数があります。
このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
アロー関数はフロントエンドインタビューにおける高頻度のテストポイントです。アロー関数はES6のAPIです。ご存知の方も多いと思います。通常の関数に比べて構文が単純なので、みんなに深く愛されてます。
1. 基本構文
ES6 では、矢印 =>
を使用してアロー関数を定義できます。具体的な構文は、簡単な例を見てみましょう:
// 箭头函数 let fun = (name) => { // 函数体 return `Hello ${name} !`; }; // 等同于 let fun = function (name) { // 函数体 return `Hello ${name} !`; };
アロー関数の定義は、数学的構文では通常の関数よりもはるかに簡単であることがわかります。アロー関数は、function
キーワードを省略し、アロー =>
を使用して関数を定義します。関数のパラメーターは =>
の前のかっこ内に配置され、関数本体は =>
の後の中括弧内に配置されます。
アロー関数のパラメータについて:
① アロー関数にパラメータがない場合は、空の括弧を記述します。
② アロー関数にパラメータが 1 つしかない場合は、パラメータを囲む括弧を省略することもできます。
③ アロー関数に複数のパラメータがある場合は、パラメータをカンマ (,) で区切って括弧で囲みます。
// 没有参数 let fun1 = () => { console.log(111); }; // 只有一个参数,可以省去参数括号 let fun2 = name => { console.log(`Hello ${name} !`) }; // 有多个参数 let fun3 = (val1, val2, val3) => { return [val1, val2, val3]; };
アロー関数の関数本体について:
① アロー関数の関数本体のコードが 1 行だけの場合、単に変数を返すか、単純な JS 式を返す場合は、関数本体の中括弧 { } を省略できます。
let f = val => val; // 等同于 let f = function (val) { return val }; let sum = (num1, num2) => num1 + num2; // 等同于 let sum = function(num1, num2) { return num1 + num2; };
② アロー関数の関数本体に、オブジェクトを返すコードが 1 行しかない場合は、次のように記述できます。
// 用小括号包裹要返回的对象,不报错 let getTempItem = id => ({ id: id, name: "Temp" }); // 但绝不能这样写,会报错。 // 因为对象的大括号会被解释为函数体的大括号 let getTempItem = id => { id: id, name: "Temp" };
③ If アロー関数の関数本体にはステートメントが 1 つだけあり、値を返す必要はありません (最も一般的なのは関数を呼び出すことです)。このステートメントの前の #
let fn = () => void doesNotReturn();
最も一般的なアロー関数の目的は、コールバック関数を簡素化することです。
// 例子一 // 正常函数写法 [1,2,3].map(function (x) { return x * x; }); // 箭头函数写法 [1,2,3].map(x => x * x); // 例子二 // 正常函数写法 var result = [2, 5, 1, 4, 3].sort(function (a, b) { return a - b; }); // 箭头函数写法 var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);
#2. アロー関数と通常の関数の違い
##1. 構文がより簡潔で明確になります
上記の基本的な構文の例からわかるように、アロー関数の定義は、通常の関数の定義よりもはるかに単純、明確、高速です。2. アロー関数は独自の this を作成しません (重要!! 詳しく理解してください!!)
まずは MDN のアロー関数を見てみましょうこれについての説明。
アロー関数は独自の this
を作成しないため、独自の
を持たず、その上位レベルからのみ開始されます。独自のスコープ チェーンの際にその位置をキャプチャします (定義されるとき、呼び出されるときではありません) 外部実行環境のthis
#definitionを継承します。
アロー関数には独自の
this
がありません。
##this を取得し、この this 値を継承します。したがって、アロー関数内の this
のポイントは、定義時にすでに決定されており、後で変更されることはありません。
例を見てみましょう: <pre class="brush:js;toolbar:false;">var id = &#39;Global&#39;;
function fun1() {
// setTimeout中使用普通函数
setTimeout(function(){
console.log(this.id);
}, 2000);
}
function fun2() {
// setTimeout中使用箭头函数
setTimeout(() => {
console.log(this.id);
}, 2000)
}
fun1.call({id: &#39;Obj&#39;}); // &#39;Global&#39;
fun2.call({id: &#39;Obj&#39;}); // &#39;Obj&#39;</pre>
上の例では、関数 fun1
の
で通常の関数が使用されています。関数は 2 秒後に実行されます。この時点で関数は実際にはグローバル スコープで実行されるため、
this は Window
オブジェクトと this.id## を指します。 # グローバル変数
id を指すため、出力は
'Global' になります。
ただし、関数
fun2 の
setTimeout はアロー関数を使用しています。このアロー関数の
this は定義時に決定され、その外層を継承します
#fun2 の実行環境に ##this
があり、fun2
が呼び出されると、this
は call によってオブジェクト ## に変更されます。
メソッド #{id: 'Obj'} であるため、
'Obj' が出力されます。
別の例を見てみましょう:
var id = 'GLOBAL'; var obj = { id: 'OBJ', a: function(){ console.log(this.id); }, b: () => { console.log(this.id); } }; obj.a(); // 'OBJ' obj.b(); // 'GLOBAL'
上の例では、オブジェクト
obj のメソッド
a は、通常の関数 ## を使用して定義されています。 #通常の関数 オブジェクトのメソッドとして呼び出された場合、
this は、それが属するオブジェクト を指します。したがって、
this.id は obj.id
であるため、'OBJ'
が出力されます。
ただし、メソッド b はアロー関数を使用して定義されており、アロー関数の
this は実際には、それが定義されているグローバル実行環境の this
を継承するため、 Window
オブジェクトなので、'GLOBAL'
が出力されます。 (ここで、オブジェクトを定義する中括弧
{} は別個の実行環境を形成できないことに注意してください。オブジェクトは依然としてグローバル実行環境内にあります!!
)<p><strong>3、箭头函数继承而来的this指向永远不变(重要!!深入理解!!)</strong></p>
<p>上面的例子,就完全可以说明箭头函数继承而来的<code>this
指向永远不变。对象obj
的方法b
是使用箭头函数定义的,这个函数中的this
就永远指向它定义时所处的全局执行环境中的this
,即便这个函数是作为对象obj
的方法调用,this
依旧指向Window
对象。
4、.call()/.apply()/.bind()无法改变箭头函数中this的指向
.call()
/.apply()
/.bind()
方法可以用来动态修改函数执行时this
的指向,但由于箭头函数的this
定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this
的指向,虽然这么做代码不会报错。
var id = 'Global'; // 箭头函数定义在全局作用域 let fun1 = () => { console.log(this.id) }; fun1(); // 'Global' // this的指向不会改变,永远指向Window对象 fun1.call({id: 'Obj'}); // 'Global' fun1.apply({id: 'Obj'}); // 'Global' fun1.bind({id: 'Obj'})(); // 'Global'
5、箭头函数不能作为构造函数使用
我们先了解一下构造函数的new都做了些什么?简单来说,分为四步: ① JS内部首先会先生成一个对象; ② 再把函数中的this指向该对象; ③ 然后执行构造函数中的语句; ④ 最终返回该对象实例。
但是!!因为箭头函数没有自己的this
,它的this
其实是继承了外层执行环境中的this
,且this
指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new
调用时会报错!
let Fun = (name, age) => { this.name = name; this.age = age; }; // 报错 let p = new Fun('cao', 24);
6、箭头函数没有自己的arguments
箭头函数没有自己的arguments
对象。在箭头函数中访问arguments
实际上获得的是外层局部(函数)执行环境中的值。
// 例子一 let fun = (val) => { console.log(val); // 111 // 下面一行会报错 // Uncaught ReferenceError: arguments is not defined // 因为外层全局环境没有arguments对象 console.log(arguments); }; fun(111); // 例子二 function outer(val1, val2) { let argOut = arguments; console.log(argOut); // ① let fun = () => { let argIn = arguments; console.log(argIn); // ② console.log(argOut === argIn); // ③ }; fun(); } outer(111, 222);
上面例子二,①②③处的输出结果如下:
很明显,普通函数outer
内部的箭头函数fun
中的arguments
对象,其实是沿作用域链向上访问的外层outer
函数的arguments
对象。
可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表!!
7、箭头函数没有原型prototype
let sayHi = () => { console.log('Hello World !') }; console.log(sayHi.prototype); // undefined
8、箭头函数不能用作Generator函数,不能使用yeild关键字
【相关推荐:javascript视频教程、web前端】
以上がes6のアロー関数と通常の関数の違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。