# this 的指向

this 的指向大概可以分为 5 种:

  • 函数正常调用时:函数中的 this 指向函数所在的执行上下文。
  • 函数作为对象的属性被调用时:此时,函数中的 this 指向这个对象(特别的是作为 DOM 事件的回调函数时,就是指向 DOM 对象)。
  • 箭头函数中的 this:箭头函数中的 this 始终指向定义时所在的执行上下文中的 this(在全局定义的箭头函数中的 this 指向 window,在函数中定义的箭头函数的 this 指向它所在的包裹函数中的 this,这个包裹函数的 this 又需要根据调用方式来判断指向谁)。 顺便补充:
    1. 箭头函数不能作为构造函数调用,即不能用 new,否则会抛出错误(function is not a constructor)。
    2. 不可以使用 arguments 对象,该对象在箭头函数内不存在,但是可以使用...rest形式的参数代替。
    3. 不可以使用yield命令,因此箭头函数不能作为 Generator 函数使用。
  • 使用 call、apply、bind 时:函数中的 this 指向第一个参数。
  • 使用 new 调用构造函数:new 的大致过程为:
    • 创建一个空的简单 JavaScript 对象(即 {} ),且其原型对象为构造函数的原型对象
    • 将步骤 1 新创建的对象作为构造函数的上下文 this ,执行后得到返回值
    • 如果该函数没有返回引用类型的值(null 除外),则返回 this,否则返回该引用类型的值。
function test() {
  var name = 'test';
  console.log(this.name);
}
var arrowFn = () => {
  var name = 'arrow function';
  console.log(this.name);
};
var name = 'window';
test(); // window
var obj = { name: 'obj', sayName: test };
obj.sayName(); // obj
test.call({ name: 'call name' }); // call name
test.bind({ name: 'bind name' })(); // bind name
// 箭头函数的this的指向在定义时确定,且不会改变。注意是指向不会变。
arrowFn(); // window
var obj = { name: 'obj', sayName: arrowFn };
obj.sayName(); // window
arrowFn.call({ name: 'call name' }); // window
arrowFn.bind({ name: 'bind name' })(); // window
// 指向没变,还是window,变得是指向的全局对象的属性的值。
name = 'global';
obj.sayName(); // global