Skip to content

确定this指向

  • 在函数体中,非显式或隐式地简单调用函数时,在严格模式下,函数内的 this 会被绑定到 undefined 上,在非严格模式下则会被绑定到全局对象 window/global 上。
  • 一般使用 new 方法调用构造函数时,构造函数内的 this 会被绑定到新创建的对象上。
  • 一般通过 call/apply/bind 方法显式调用函数时,函数体内的 this 会被绑定到指定参数的对象上。
  • 一般通过上下文对象调用函数时,函数体内的 this 会被绑定到该对象上,也就是“谁调用它,this 就指向谁”
  • 在箭头函数中,this 的指向是由外层(函数或全局)作用域来决定的。

全局环境中的 this

非严格模式下,this 指向全局对象,严格模式下,this 会绑定到 undefined

js
var a = 1;

function foo() {
	console.log(this.a);
}

foo(); // 1,非严格模式下,this 指向全局对象 Window,这里相当于 Window.a

function bar() {
	"use strict";
	console.log(this.a);
}

bar(); // Uncaught TypeError: Cannot read property 'a' of undefined,严格模式下,this 会绑定到 undefined,尝试从 undefined 读取属性会报错

上下文对象调用中的 this

js
var obj = {
	a: 2,
	foo: foo, // <-- foo函数 的调用位置
};

obj.foo(); // 2,foo 在调用位置有上下文对象 obj,this 会隐式地绑定到 obj,this.a 相当于 obj.a
  1. 使用函数别名调用时
js
var bar = obj.foo; // bar === foo了,跟obj就没关系了

bar();
// 1,赋值并不会改变引用本身,使用函数别名调用时,
// bar 虽然是 obj.foo 的一个引用,但是实际上引用的还是 foo 函数本身,
  1. 函数作为参数传递时
js
function bar(fn) {
	fn(); // <-- 调用位置
}

bar(obj.foo); // 1, 参数传递也是一种隐式赋值,即使传入的是函数,这里相当于 fn = obj.foo,所以 fn 实际上引用的还是 foo 函数本身,this 应用默认绑定
  1. this 指向绑定事件的元素。注意它和 target 的区别,target 是指向触发事件的元素

显式绑定

我们知道 callapplybind 等方法可以改变 this 的指向

apply: apply接受两个参数,第一个参数是this的指向,第二个参数是函数接受的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,默认指向window(在浏览器中),使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。

call: call方法的第一个参数也是this的指向,后面传入的是一个参数列表(注意和apply传参的区别)。当一个参数为null或undefined的时候,表示指向window(在浏览器中),和apply一样,call也只是临时改变一次this指向,并立即执行。

点击执行,可以在控制台中查看可能的执行结果

箭头函数

箭头函数的 this 指向始终为外层的作用域。简单来说,箭头函数的 this 就是它外面第一个不是箭头函数的函数的 this.

js箭头函数本质上是一个匿名函数表达式,其内this的指向是对应语句在创建执行上下文时确定的,而不是在调用时确定的

点击执行,可以在控制台中查看可能的执行结果

实现绑定this的方法

手写apply

点击执行,可以在控制台中查看可能的执行结果

手写call

点击执行,可以在控制台中查看可能的执行结果

手写bind

点击执行,可以在控制台中查看可能的执行结果

面试题

点击执行,可以在控制台中查看可能的执行结果

点击执行,可以在控制台中查看可能的执行结果

点击执行,可以在控制台中查看可能的执行结果

手写 call、apply、bind

苏ICP备2025160170号-1 | 前端进化之路 | Released under the MIT License.