最近被问到一个问题:

javaScript 中的箭头函数 ( => ) 和普通函数 ( function ) 有什么区别?

我当时第一反应是:这很简单啊,不就是一种简化的写法吗,还依稀记得对this指向有影响。好吧,记不清楚了,然后迅速开始百度之旅~~

箭头函数

引入箭头函数有两个方面的作用:更简短的函数并且没有定义this绑定。

基础语法:

  1. (arg1, arg2, ..., argn) => {函数声明};

不绑定this

在箭头函数出现之前,每个新定义的函数都有它自己的this值。箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this,总是指向函数定义生效时所在的对象。

  1. // 1. `Person()`构造函数定义 this 作为它自己实例,而`add()`函数定义 this 作为全局对象。
  2. function Person() {
  3. this.age = 10;
  4. foo: setInterval(function add() {
  5. this.age ++;
  6. console.log(this.age);
  7. }, 100);
  8. }
  9. new Person().foo;
  10. // 2. 通过将this值分配给封闭的变量,可以解决this问题。
  11. function Person() {
  12. let _this = this;
  13. _this.age = 10;
  14. foo: setInterval(function add() {
  15. _this.age ++;
  16. console.log(this.age);
  17. }, 100);
  18. }
  19. new Person().foo;
  20. // 3. this正确指向person对象
  21. function Person() {
  22. this.age = 10;
  23. foo: setInterval(() => {
  24. this.age ++;
  25. console.log(this.age);
  26. }, 1000);
  27. }
  28. new Person().foo;

不能作为构造函数

  1. let Person = () => {};
  2. let person = new Person();
  3. console.log(person); // TypeError: Foo is not a constructor

不绑定arguments

  1. // 箭头函数内部的变量arguments,其实是函数foo的arguments变量。
  2. function foo() {
  3. setTimeout(() => {
  4. console.log(arguments);
  5. }, 100);
  6. }
  7. foo(1, 2, 3) // ['1': 1, '2': 2, '3': 3]
  8. //
  9. function foo() {
  10. let f = (...args) => args[0];
  11. return f(2);
  12. }
  13. foo(1); // 2

没有prototype属性

  1. let Person = () => {};
  2. console.log(Person.prototype); // undefined

解析顺序

箭头函数中的箭头不是运算符,但箭头函数具有与常规函数不同的特殊运算符优先级解析规则。

  1. let foo;
  2. foo = foo || function() {}; // ok
  3. foo = foo || () => {}; // SyntaxError: invalid arrow-function arguments
  4. foo = foo || (() => {}); // ok