this 一问到底

143 阅读2分钟

函数正常执行(foo())时的 this 指向

在函数内部,this 的值取决于函数被调用的方式。

function foo() {
  return this;
}

console.log(foo() === window); // TRUE

在严格模式下,如果进入执行环境时没有设置 this 的值,thisundefined

function bar() {
  "use strict"; // 严格模式
  return this;
}

console.log(bar() === undefined); // TRUE

箭头函数的 this 指向

上下文。

箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this

this 会被设置为他被创建时的环境(例如:全局对象)。

这同样适用于在其他函数内创建的箭头函数:这些箭头函数的 this 被设置为封闭的词法环境。

var foo = {
  bar: () => {
    console.log(this); // window
  },
};

箭头函数中的 this 指向 window,因为上面这段代码相当于:

var foo = {};
foo.bar = () => {
  console.log(this); // window
};

class 类中箭头函数定义的方法,其 this 指向类实例。

class A {
  foo = () => {
    return this;
  };
}

var a = new A();

console.log(a.foo() === a); // TRUE

this 可通过哪些方式被修改

bindcallapply

箭头函数的 this 可被修改吗

不可以。

箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this

箭头函数的 this 是依赖上下文的,函数定义时 this 是什么就是什么。能改变 this 指向的 bindcallapply、方法调用等对 this 都是无效的。

通过 callapply 等调用一个箭头函数时,只能传递参数,不能绑定 this,他们的第一个参数会被忽略。

bind 过的函数还可以通过 callapply 修改 this

不可以。

bind 方法用来设置函数的 this 值,而不用考虑函数是如何被调用的。

调用 func.bind(someObject) 会创建一个与 func 具有相同函数体和作用域的函数,但是在这个新函数中,this 将永久地被绑定到了 bind 的第一个参数,无论这个函数是如何被调用的。

这个是写在标准里的。

bind 会创建一个新的绑定函数,这个绑定函数包装了原来的函数对象,调用时会直接执行包装函数。

bind 过的函数(绑定函数)内部有一个 [[BoundThis]] 属性,调用绑定函数时,this 会被忽略,只读取 [[BoundThis]]

函数作为对象成员调用(foo.bar())是 this 的指向

指向这个对象(foo)。

var foo = {
  bar: function () {
    "use strict"; // 这里是严格模式
    return this;
  },
};

console.log(foo.bar() === foo); // true

// --------------
// 非严格模式也是一样的
var foo = {
  bar: function () {
    return this;
  },
};

console.log(foo.bar() === foo); // true

// --------------
// 箭头函数
var foo = {
  bar: () => {
    return this;
  },
};

console.log(foo.bar() === window); // true