Es6 - 箭头函数

105 阅读2分钟
  • 没有自己的 this、arguments、super、new.target
  • call、apply 不能改变 this 指向(不存在this)
  • this 指向函数定义时所在的作用域
  • 严格模式下 this 指向 window
  • 不能用作构造器去 new 对象 (不存在this)
function Foo() {
  console.log(new.target); // Foo
}
new Foo();

class Rectangle {
  constructor() {
    console.log(new.target);
  }
}
class Square extends Rectangle {}
new Rectangle(); // Rectangleåå
new Square(); // Square

1、使用场景

让函数变得更加简短

var elements = ["Hydrogen", "Helium", "Lithium", "Beryllium"];

elements.map(function (element) {
  return element.length;
}); // 返回数组:[8, 6, 7, 9]

// 上面的普通函数可以改写成如下的箭头函数
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数的函数体只有一个 `return` 语句时
// 可以省略 `return` 关键字和方法体的花括号
elements.map((element) => element.length); // [8, 6, 7, 9]

// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,
// 而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
// [8, 6, 7, 9]
elements.map(({ length: lengthFooBArX }) => lengthFooBArX);

this 指向函数定义时所在的作用域(本身不含this)

function Person() {
  this.age = 0;
  setInterval(() => {
    this.age++; // |this| 正确地指向 p 实例
  }, 1000);
}

var p = new Person();

call、apply 不能改变 this 指向(本身不含this)

var adder = {
  base: 1,

  add: function (a) {
    var f = (v) => v + this.base;
    return f(a);
  },

  addThruCall: function (a) {
    var f = (v) => v + this.base;
    var b = {
      base: 2,
    };

    return f.call(b, a);
  },
};

console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2

使用箭头函数作为方法

("use strict");

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function () {
    console.log(this.i, this);
  },
};
obj.b(); // undefined, Window{...}
obj.c(); // 10, Object {...}

与严格模式的关系 :指向window

// 严格模式下,普通函数内 this 为 undefined 
var f = function() { 'use strict'; return this; }; 
f() === window; // false


// 严格模式下,箭头函数内this指向window
var f = () => { 'use strict'; return this; };
f() === window; // true

使用 new 操作符 ( 没有自己的this )

  • 箭头函数不能用作构造器
  • 和 new一起用会抛出错误
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

2、箭头函数不适用场合

对象不构成单独的作用域,导致 jumps 箭头函数定义时的作用域就是全局作用域

const cat = {
  lives: 9,
  jumps: () => {
    this.lives--; // this 指向window
  },
};

监听函数是一个箭头函数,导致里面的this就是全局对象

var button = document.getElementById("press");
button.addEventListener("click", () => {
  this.classList.toggle("on");
});