JavaScript箭头函数与普通函数的区别?

来源 | https://learn-anything.cn/java-script-arrow-functions
一、什么是箭头函数?
1、(...args) => expression
2、 (...args) => { body }
二、不同表达形式:
1、参数不同,写法不同
// 1、没有参数let test = () => alert("Hello!");// 2、只有一个参数:() 可以省略let test = n => n * 2;let test = (n) => n * 2;// 等价于下面普通函数let test = function (n) {return expression;};
2、表达式不同,写法不同
// 1、只有一行 return 表达式,可省略 return 和 {}let func = (arg1, arg2, ...argN) => {return expression;}// 等价于下面箭头函数let func = (arg1, arg2, ...argN) => expression// 等价于下面普通函数。let func = function (arg1, arg2, ...argN) {return expression;};
3、用于条件运算符
let age = prompt("What is your age?", 18);let welcome = (age < 18) ?() => alert('Hello') :() => alert("Greetings!");welcome();
4、用于数组遍历
var elements = ['Hydrogen','Helium','Lithium','Beryllium'];// 1、普通函数写法:elements.map(function (element) {return element.length;});// 2、箭头函数写法:elements.map((element) => {return element.length;});// 3、只有一个参数,可省略()elements.map(element => {return element.length;});// 4、表达式只有一行return语句,可省略 return 和 {}elements.map(element => element.length);// 5、参数解构方式// elements数组中每一项都有length属性,可以通过参数解构获得结果,方法如下:// 注意:lengthFooBArX只是一个变量,可以替换成任意合法变量名elements.map(({ "length": lengthFooBArX }) => lengthFooBArX);// 以上输出结果都为: [8, 6, 7, 9]
5、用于递归
var fact = (x) => (x == 0 ? 1 : x * fact(x - 1));fact(5);// 输出:120
6、使用闭包
// 1、箭头函数体的闭包( i=0 是默认参数)var Add = (i = 0) => {return (() => (++i))};var v = Add();v(); //1v(); //2// 因为仅有一个返回,return 及括号()也可以省略var Add = (i = 0) => () => (++i);
7、其他形式举例
// 1、空的箭头函数返回 undefinedlet empty = () => { };// 2、立即执行函数表达式,返回 "foobar"(() => 'foobar')();// 3、更简明的promise链promise.then(a => {// ...}).then(b => {// ...});// 4、无参数箭头函数在视觉上容易分析setTimeout(() => {console.log('I happen sooner');setTimeout(() => {// deeper codeconsole.log('I happen later');}, 1);}, 1);
三、重要特性
1、没有 arguments
// 1、普通函数中的arguments正确使用:function foo(n) {// 隐式绑定 foo函数的参数 与 arguments对象.// arguments[0] 表示传给foo函数的第一个参数,也就是nvar f = () => arguments[0] + n;return f();}foo(1); // 2foo(3); // 6foo(3, 2);//6// 2、箭头函数中无法使用arguments// ReferenceError: arguments is not definedvar func = (a, b) => {return arguments[0];}
2、没有prototype属性
var Foo = () => {};console.log(Foo.prototype); // undefined
3、不能使用new
箭头函数没有this,不能用作构造函数,也就无法使用 new
var Foo = () => {};var foo = new Foo(); // TypeError: Foo is not a constructor
四、需要()的场景
1、对象作为表达式
用 ()包裹 {}表示的对象来作为表达式返回,否则 {}会作为表达式来解析,出现语法错误。
// Calling func() returns undefined!var func = () => { foo: 1 };// SyntaxError: function statement requires a namevar func = () => { foo: function() { } };// 正确写法如下:var func = () => ({ foo: 1 });var func = () => ({ foo: function () { } });
2、换行
// 1、语法错误:SyntaxError: expected expression, got '=>'var func = ()=> 1;// 2、正确,可以在 => 后换行var func = (a, b, c) =>1;// 3、正确,用 () 来换行var func = (a, b, c) => (1);// 4、正确,用 () 来换行var func = (a,b,c) => 1;
3、作为单独表达式
let callback;// 1、正确callback = callback || function () { };// 2、错误:SyntaxError: invalid arrow-function argumentscallback = callback || () => { };// 3、正确callback = callback || (() => { }); // ok
五、箭头函数没有this
普通函数、对象方法中的this,都是在运行时定义。
普通函数的this 等于 undefined,无法调用;
对象方法的this,指向对象本身。
箭头函数,不会定义自己的this,它只会继承自己上一层作用域的this。
1、对象中的箭头函数
var obj = {i: 10,b: () => console.log(this.i, this),c: function () {console.log(this.i, this)}}obj.b();// 输出结果:undefined, Window{...}// 箭头函数b,没有上层作用域可以继承this,也就无法访问。obj.c();// 输出结果:10, Object {...}
2、正确使用箭头函数中的this
// 实例1:function Person() {this.age = 0;// 箭头函数作为 setInterval 的一个参数,继承了 thissetInterval(() => {this.age++;console.log("age:", this.age);}, 1000);}var p = new Person();// 实例2:// 箭头函数 student 继承了 showList 的 thislet group = {title: "Our Group",students: ["John", "Pete", "Alice"],showList() {this.students.forEach(student => alert(this.title + ': ' + student));}};group.showList();
3、普通函数无法访问this
# 普通函数中 this 等于 undefined ,所用 this.title 必然因为无法识别而报错let group = {title: "Our Group",students: ["John", "Pete", "Alice"],showList() {this.students.forEach(function (student) {// Error: Cannot read property 'title' of undefinedalert(this.title + ': ' + student)});}};group.showList();
本文完~
学习更多技能
请点击下方公众号
![]()

评论
