Heim > Artikel > Web-Frontend > Was ist der Unterschied zwischen Pfeilfunktionen und gewöhnlichen Funktionen in es6?
Unterschiede: 1. Die Definition der Pfeilfunktion ist viel einfacher, klarer und schneller als die Definition einer gewöhnlichen Funktion. 2. Die Pfeilfunktion erstellt keine eigene Funktion, die gewöhnliche Funktion jedoch nicht als Konstruktor verwendet werden. 4. Die Pfeilfunktion hat keine eigenen Argumente, die Pfeilfunktion jedoch.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, ECMAScript Version 6, Dell G3-Computer.
Die Pfeilfunktion ist ein hochfrequenter Testpunkt in Front-End-Interviews. Ich glaube, viele Leute wissen, dass ihre Syntax einfacher ist als bei gewöhnlichen Funktionen.
1. Grundlegende Syntax
ES6 ermöglicht die Verwendung von Pfeilen =>
zum Definieren von Pfeilfunktionen. Schauen wir uns für die spezifische Syntax ein einfaches Beispiel an: =>
来定义箭头函数,具体语法,我们来看一个简单的例子:
// 箭头函数 let fun = (name) => { // 函数体 return `Hello ${name} !`; }; // 等同于 let fun = function (name) { // 函数体 return `Hello ${name} !`; };
可以看出,定义箭头函在数语法上要比普通函数简洁得多。箭头函数省去了function
关键字,采用箭头=>
来定义函数。函数的参数放在=>
前面的括号中,函数体跟在=>
后的花括号中。
关于箭头函数的参数:
① 如果箭头函数没有参数,直接写一个空括号即可。
② 如果箭头函数的参数只有一个,也可以省去包裹参数的括号。
③ 如果箭头函数有多个参数,将参数依次用逗号(,)分隔,包裹在括号中即可。
// 没有参数 let fun1 = () => { console.log(111); }; // 只有一个参数,可以省去参数括号 let fun2 = name => { console.log(`Hello ${name} !`) }; // 有多个参数 let fun3 = (val1, val2, val3) => { return [val1, val2, val3]; };
关于箭头函数的函数体:
① 如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的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; };
② 如果箭头函数的函数体只有一句代码,就是返回一个对象,可以像下面这样写:
// 用小括号包裹要返回的对象,不报错 let getTempItem = id => ({ id: id, name: "Temp" }); // 但绝不能这样写,会报错。 // 因为对象的大括号会被解释为函数体的大括号 let getTempItem = id => { id: id, name: "Temp" };
③ 如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void
关键字
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);
二、箭头函数与普通函数的区别
1、语法更加简洁、清晰
从上面的基本语法示例中可以看出,箭头函数的定义要比普通函数定义简洁、清晰得多,很快捷。
2、箭头函数不会创建自己的this(重要!!深入理解!!)
我们先来看看MDN上对箭头函数this
的解释。
箭头函数不会创建自己的
this
,所以它没有自己的this
,它只会从自己的作用域链的上一层继承this
。
箭头函数没有自己的this
,它会捕获自己在定义时(注意,是定义时,不是调用时)所处的外层执行环境的this
,并继承这个this
值。所以,箭头函数中this
的指向在它被定义的时候就已经确定了,之后永远不会改变。
来看个例子:
var id = 'Global'; function fun1() { // setTimeout中使用普通函数 setTimeout(function(){ console.log(this.id); }, 2000); } function fun2() { // setTimeout中使用箭头函数 setTimeout(() => { console.log(this.id); }, 2000) } fun1.call({id: 'Obj'}); // 'Global' fun2.call({id: 'Obj'}); // 'Obj'
上面这个例子,函数fun1
中的setTimeout
中使用普通函数,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'
。(这里要注意,定义对象的大括号{}
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'
Wie Sie Wie Sie sehen, ist das Definieren von Pfeilfunktionen in Bezug auf die mathematische Syntax viel einfacher als gewöhnliche Funktionen. Die Pfeilfunktion lässt das Schlüsselwort function
weg und verwendet den Pfeil =>
, um die Funktion zu definieren. Die Parameter der Funktion stehen in den Klammern vor =>
und der Funktionskörper steht in den geschweiften Klammern nach =>
.
let Fun = (name, age) => { this.name = name; this.age = age; }; // 报错 let p = new Fun('cao', 24);🎜🎜Über den Funktionskörper der Pfeilfunktion: 🎜🎜🎜🎜①🎜 Wenn der Funktionskörper der Pfeilfunktion nur eine Codezeile enthält, die einfach eine Variable oder einen einfachen JS-Ausdruck zurückgibt, werden die geschweiften Klammern der Der Funktionskörper kann weggelassen werden. 🎜
// 例子一 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);🎜🎜②🎜 Wenn der Funktionskörper der Pfeilfunktion nur eine Anweisung hat, nämlich ein Objekt zurückzugeben, können Sie es so schreiben: 🎜
let sayHi = () => { console.log('Hello World !') }; console.log(sayHi.prototype); // undefined🎜🎜③🎜 Wenn der Funktionskörper der Pfeilfunktion nur eine hat Anweisung und muss keinen Wert zurückgeben (am häufigsten wird der Aufruf einer Funktion verwendet). Sie können vor dieser Anweisung ein Schlüsselwort
void
hinzufügen🎜rrreee🎜Pfeilfunktionen werden am häufigsten verwendet Vereinfachen Sie die Rückruffunktion. 🎜rrreee🎜🎜🎜 2. Der Unterschied zwischen Pfeilfunktionen und gewöhnlichen Funktionen 🎜🎜🎜🎜🎜 1. Die Syntax ist prägnanter und klarer 🎜🎜🎜 Wie aus den grundlegenden Syntaxbeispielen oben ersichtlich ist, ist die Definition von Pfeilfunktionen einfacher als die Definition gewöhnlicher Funktionen, viel klarer und schneller. 🎜🎜🎜2. Die Pfeilfunktion erstellt kein eigenes This (Wichtig!! Tiefes Verständnis!!) 🎜🎜🎜 Schauen wir uns zunächst die Erklärung der Pfeilfunktion this
auf MDN an . 🎜🎜🎜Die Pfeilfunktion erstellt kein eigenes this
, daher hat sie kein eigenes this
, sie erbt nur von der oberen Ebene ihrer eigenen Bereichskette this
. 🎜🎜🎜Die Pfeilfunktion verfügt nicht über einen eigenen this
, sie erfasst den this der 🎜äußeren Ausführungsumgebung, wo er sich bei 🎜Definition🎜 befindet (beachten Sie, wenn er definiert ist, nicht). wenn es aufgerufen wird)
🎜 und diesen diesen
-Wert erben. Daher wird die Ausrichtung von this
in der Pfeilfunktion bei der Definition festgelegt und wird sich später nie ändern. 🎜🎜Schauen wir uns ein Beispiel an: 🎜rrreee🎜Im obigen Beispiel wird eine normale Funktion in setTimeout
in der Funktion fun1
verwendet, wenn die Funktion nach 2 ausgeführt wird Sekunden wird die Funktion tatsächlich im globalen Bereich ausgeführt, sodass this
auf das Window
-Objekt und this.id
auf das Objekt zeigt globale Variable id
Geben Sie also 'Global'
aus.
Die Pfeilfunktion wird jedoch in setTimeout
in der Funktion fun2
verwendet. Der this
dieser Pfeilfunktion wird bei der Definition bestimmt und erbt ihn . this
in der Ausführungsumgebung des äußeren fun2
, und wenn fun2
aufgerufen wird, ist this
aufgerufen Die Code>-Methode wird in das Objekt <code>{id: 'Obj'
geändert, sodass 'Obj'
ausgegeben wird. 🎜🎜Sehen wir uns ein weiteres Beispiel an: 🎜rrreee🎜Im obigen Beispiel wird die Methode a
des Objekts obj
mithilfe einer gewöhnlichen Funktion definiert. 🎜Wenn die gewöhnliche Funktion ist this
wird als Methode des Objekts aufgerufen und zeigt auf das Objekt, zu dem es gehört 🎜. Daher ist this.id
obj.id
, sodass 'OBJ'
ausgegeben wird.
Die Methode b
wird jedoch mithilfe einer Pfeilfunktion this
in der Pfeilfunktion definiert und erbt tatsächlich this
in der globalen Ausführungsumgebung, in der sie definiert ist >, also zeigt es auf das Window
-Objekt, also wird 'GLOBAL'
ausgegeben. (🎜Hier ist zu beachten, dass die geschweiften Klammern {}
, die das Objekt definieren, keine separate Ausführungsumgebung bilden können, es befindet sich immer noch in der globalen Ausführungsumgebung!!🎜)🎜3、箭头函数继承而来的this指向永远不变(重要!!深入理解!!)
上面的例子,就完全可以说明箭头函数继承而来的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前端】
Das obige ist der detaillierte Inhalt vonWas ist der Unterschied zwischen Pfeilfunktionen und gewöhnlichen Funktionen in es6?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!