Maison > Article > interface Web > Quelle est la différence entre les fonctions fléchées et les fonctions ordinaires dans es6
Différences : 1. La définition de la fonction flèche est beaucoup plus simple, plus claire et plus rapide que la définition de la fonction ordinaire ; 2. La fonction flèche ne crée pas son propre ceci, mais la fonction ordinaire le fait ; utilisé comme constructeur.La fonction flèche peut être utilisée comme constructeur;4. La fonction flèche n'a pas ses propres arguments, mais la fonction flèche en a.
L'environnement d'exploitation de ce tutoriel : système Windows 7, ECMAScript version 6, ordinateur Dell G3.
La fonction Arrow est un point de test à haute fréquence dans les entretiens frontaux. La fonction Arrow est une API d'ES6, je pense que beaucoup de gens la connaissent. Parce que sa syntaxe est plus simple que les fonctions ordinaires, elle est profondément appréciée par tout le monde.
1. Syntaxe de base
ES6 permet l'utilisation de flèches =>
pour définir les fonctions de flèches. Pour la syntaxe spécifique, regardons un exemple simple : =>
来定义箭头函数,具体语法,我们来看一个简单的例子:
// 箭头函数 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'
Comme vous. Comme vous pouvez le voir, la définition des fonctions fléchées est beaucoup plus simple que les fonctions ordinaires en termes de syntaxe mathématique. La fonction flèche omet le mot-clé function
et utilise la flèche =>
pour définir la fonction. Les paramètres de la fonction sont placés entre parenthèses avant =>
, et le corps de la fonction est placé entre accolades après =>
.
let Fun = (name, age) => { this.name = name; this.age = age; }; // 报错 let p = new Fun('cao', 24);🎜🎜À propos du corps de la fonction flèche : 🎜🎜🎜🎜①🎜 Si le corps de la fonction flèche n'a qu'une seule ligne de code, qui renvoie simplement une variable ou une simple expression JS, les accolades du le corps de la fonction peut être omis { }. 🎜
// 例子一 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);🎜🎜②🎜 Si le corps de la fonction flèche n'a qu'une seule instruction, qui doit renvoyer un objet, vous pouvez l'écrire comme ceci : 🎜
let sayHi = () => { console.log('Hello World !') }; console.log(sayHi.prototype); // undefined🎜🎜③🎜 Si le corps de la fonction flèche n'a qu'une seule instruction et n'a pas besoin de renvoyer de valeur (le plus courant est d'appeler une fonction), vous pouvez ajouter un mot-clé
void
devant cette instruction🎜rrreee🎜L'utilisation la plus courante des fonctions fléchées est de simplifier la fonction de rappel. 🎜rrreee🎜🎜🎜 2. La différence entre les fonctions fléchées et les fonctions ordinaires 🎜🎜🎜🎜🎜 1. La syntaxe est plus concise et claire 🎜🎜🎜 Comme le montrent les exemples de syntaxe de base ci-dessus, la définition des fonctions fléchées est plus simple que la définition des fonctions ordinaires, beaucoup plus claire et plus rapide. 🎜🎜🎜2. La fonction flèche ne crée pas son propre this (Important !! Compréhension approfondie !!) 🎜🎜🎜 Jetons d'abord un coup d'œil à l'explication de la fonction flèche this
sur MDN. . 🎜🎜🎜La fonction flèche ne crée pas son propre this
, elle n'a donc pas son propre this
, elle héritera uniquement du de son propre niveau supérieur chaîne de portée ceci
. 🎜🎜🎜La fonction flèche n'a pas son propre this
, elle capturera le this de l'environnement d'exécution externe où il se trouve lors de la 🎜définition🎜 (attention, lorsqu'il est défini, pas lorsqu'il est appelé)
🎜, et hérite de cette cette
valeur. Par conséquent, le pointage de this
dans la fonction flèche est déterminé lors de sa définition, et ne changera jamais par la suite. 🎜🎜Regardons un exemple : 🎜rrreee🎜Dans l'exemple ci-dessus, une fonction normale est utilisée dans setTimeout
dans la fonction fun1
lorsque la fonction est exécutée après 2. secondes, la fonction est en fait exécutée dans la portée globale, donc this
pointe vers l'objet Window
et this.id
pointe vers l'objet variable globale id
. Donc, affichez 'Global'
.
Mais la fonction flèche est utilisée dans setTimeout
dans la fonction fun2
. Le this
de cette fonction flèche est déterminé lorsqu'elle est définie, et elle en hérite. . this
dans l'environnement d'exécution du fun2
externe, et lorsque fun2
est appelé, this
est . appelée La méthode code> est remplacée par l'objet <code>{id: 'Obj'>
, donc 'Obj'
est affiché. 🎜🎜Regardons un autre exemple : 🎜rrreee🎜Dans l'exemple ci-dessus, la méthode a
de l'objet obj
est définie à l'aide d'une fonction ordinaire 🎜Lorsque la fonction ordinaire est. appelé comme méthode de l'objet, this
pointe vers l'objet auquel il appartient 🎜. Par conséquent, this.id
est obj.id
, donc 'OBJ'
est affiché.
Cependant, la méthode b
est définie à l'aide d'une fonction flèche. this
dans la fonction flèche hérite en fait de this
dans l'environnement d'exécution global où elle est définie. >, donc il pointe vers l'objet Window
, donc 'GLOBAL'
est affiché. (🎜Il est à noter ici que les accolades {}
qui définissent l'objet ne peuvent pas former un environnement d'exécution séparé, il est toujours dans l'environnement d'exécution global !!🎜)🎜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前端】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!