this(箭头函数)

1. 什么是 this

this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象。

函数的调用方式决定了 this 的值(运行时绑定)。this 一旦在执行过程中被确定,就不能再更改。

2. 绑定规则

2.1 默认绑定

全局环境下调用函数,内部使用 this:

  • 非严格模式 → 指向全局变量(浏览器中为 window)。
  • 严格模式 → 指向 undefined。

2.2 隐式绑定

函数作为某个对象的方法调用时,this 指向它的上级对象。如果函数被多层对象包含,this 指向的也是它上一级的对象。

this 永远指向最后调用它的对象。

const o = {
  a: 10,
  b: {
    a: 12,
    fn() {
      console.log(this.a); // undefined
      console.log(this);   // window(默认绑定)
    }
  }
};
const j = o.b.fn;
j();

2.3 new 绑定

通过构造函数 new 关键字生成实例对象,this 指向这个实例对象。

特殊情况:

  • new 过程中遇到 return 一个对象 → this 指向返回的对象。
function fn() {
  this.user = 'xxx';
  return {};
}
const a = new fn();
console.log(a.user); // undefined
  • return 一个简单类型 → this 仍然指向实例对象(null 同理,因为 null 是空对象指针,但 new 会忽略):
function fn() {
  this.user = 'xxx';
  return 1;
}
const a = new fn();
console.log(a.user); // 'xxx'

2.4 显式修改

apply()、call()、bind() 可显式改变 this 指向。

3. 箭头函数

ES6 提供了箭头函数语法,使 this 在代码书写阶段就确定(编译时绑定)。

箭头函数体内的 this 对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。

普通函数示例

var name = 'window'; // 其实是 window.name

var A = {
  name: 'A',
  sayHello: function () { console.log(this.name); }
};

A.sayHello();         // 输出 A
A.sayHello.call(B);   // 输出 B
A.sayHello.call();     // 输出 window(不传参数指向全局)

普通函数的 this 跟使用时的对象有关。

改成箭头函数

var name = 'window';

var A = {
  name: 'A',
  sayHello: () => { console.log(this.name); }
};

A.sayHello(); // 错啦,输出的是 window(而非 A)

sayHello 这个箭头函数所在的作用域是最外层 JS 环境(没有其他函数包裹),最外层指向 window,所以 this 是 window。

改造成永远绑定 A

var name = 'window';

var A = {
  name: 'A',
  sayHello: function () {
    const s = () => console.log(this.name);
    return s;
  }
};

const sayHello = A.sayHello();
sayHello();           // 输出 A
sayHello.call(B);     // 还是 A
sayHello.call();      // 还是 A

箭头函数 s 中 this 就是定义时的外层 A.sayHello 的 this,指向 A。

使用箭头函数其他注意

  • 不能作为构造函数(没有 this、没有 prototype)。
  • 没有 arguments 对象。
  • 不能用作 Generator 函数(无 yield)。
  • call / apply / bind 无法改变箭头函数的 this。

来源整理自:我的有道云笔记