箭头函数

205 阅读2分钟

箭头函数不绑定this

箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this

var id = 1
const obj = {
  id: 2,
  foo: () => {
    console.log(this.id)
  }
}
obj.foo()

答案输出是1

为什么呢? 因为箭头函数this指向等于定义时上层作用域中的this,所以是指向最外层window

再看一个例子

var id = 1
const obj = {
  id: 2,
  foo: function () {
    setTimeout(() => {
      console.log(this.id)
    }, 1000)
  }
}
const bar = obj.foo
bar() // 1

obj.foo.call(obj) // 2

为什么他们输出结果会不一致呢?

不是说箭头函数不会被外部影响改变,callapply方法对箭头函数无效吗?

接下来我们来一步步分析,为了方便大家理解,我将上述代码通过babel转换成es5来分析,如下

// es5
var id = 1;
var obj = {
  id: 2,
  foo: function foo() {
    var _this = this;
    setTimeout(function () {
      console.log(_this.id);
    }, 1000);
  }
};
const bar = obj.foo
bar()
obj.foo.call(obj);

可以看出

箭头函数里面根本没有自己的this,而是引用的上层作用域中this

我们通过 call 来改变 this 指向改变是其父级的 this ,箭头函数里的 this 永远的指向其父级的作用域,而我们只是通过改变其父级的 this 指针,来达到箭头函数 this 的修改

箭头函数不绑定arguments,没有prototype原型对象

const f1 = function (val) { console.log(val) }
const f2 = (val) => console.log(val)
console.dir(f1)
console.dir(f2)

image.png 可以发现箭头函数没有argumentsprototype原型对象

箭头函数不绑定arguments,取而代之用rest参数…解决

const f = (...args) => {
  console.log(args)
}
f(1,2,3) // [1,2,3]

箭头函数是匿名函数,不能作为构造函数,不能使用new

我们先来看看new的原理

// new的原理
function create(Con, ...args) {
  let obj = {}
  obj.__proto__ = Con.prototype
  let result = Con.apply(obj, args)
  return result instanceof Object ? result : obj
}


通过上面已知的信息,箭头函数没有prototype,所以无法使实例的__proto__指向其构造函数的原型