彻底搞懂JavaScript中的this绑定:从四大规则到箭头函数

96 阅读5分钟

前言:为什么this如此令人困惑?

在JavaScript开发中,this 关键字无疑是最令人困惑的概念之一。很多开发者都曾在各种面试中被问及this的指向问题,也在实际项目中因为this的指向不明而遭遇bug。

this的本质是一个代词,它像一个灵活的指针,在不同的执行环境中指向不同的对象。理解this的关键在于:它的指向是在函数被调用时确定的,而不是在函数定义时

本文将系统梳理this的四大绑定规则和箭头函数的特殊行为,帮你彻底攻克这个难点。

1.为什么要有 this ?

this 提供了一个更优雅的方式隐式地传递一个对象引用,可以让代码更简洁易于复用

来看下面代码,很显然该代码就是输出打印一个名字首字母大写的一句话,如果我功能复杂一点的话,是不是context这个参数会到处传,这种情况就叫做上下文传递过于复杂了。

function identify(context){
    return context.name.toUpperCase()

}
function speak(context){
    var greeting='hello,I am'+identify(context)
    console.log(greeting);
    

}
var me={
    name:'Tom'
}
speek(me)

这时候就可以把这段代码改成用this的形式就不用参数了,这时候输出是一模一样的。此时我们先不解释这段代码怎么来的,你跟着我看完接下来的内容你就知道了怎么一回事。

function identify(){
    return this.name.toUpperCase()

}
function speek(){
    var greeting='Hello,I am'+identify.call(this)

}
var me={
    name:'Tom'
}
speek.call(me)

2.this 通常用在哪?

一般可以产生作用域的都可以用this,一般只可以在全局和函数体内,一般在函数体作用域内,this就用在这两个地方

  • this是一个代词,用在不同的地方代指不同的值,不看函数调用在哪,就看函数怎么调用。

我直接node在全局打印this,得到一个空对象{}叫做gobal

console.log(this);

在浏览器打印时就是window对象

屏幕截图 2025-11-27 180942.png 所以全局作用域 this==window所以主要还是了解函数作用域这一方面来看this的绑定规则

3.this的绑定规则

3.1 默认绑定(独立函数调用)

规则:当函数被独立调用时,函数内部的this指向全局对象(浏览器中为window,Node.js中为global)。现在用代码来看是什么意思呢?这个this在函数体内,但是它指向的是谁呢?

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

来看在浏览器下打印的结果,很显然是不是就是代指window

屏幕截图 2025-11-27 181957.png

3.2 隐式绑定

规则:当函数被一个上下文对象引用且被该对象调用,函数中的this会绑定到这个上下文对象上。

看下面这段js代码显然它是不是被obj调用了,虽然它在foo这个函数体上。

function foo(){
    console.log(this.a);
    
}
var a=1
var obj={
    foo:foo
}
obj.foo()

所以此时的this指向obj,得到的结果就是undefined

屏幕截图 2025-11-27 183138.png

隐式丢失的坑

这是面试中经常考察的重点!当函数被多层对象调用时,this指向直接调用该方法的那个对象。

以这段代码为例,foo是不是被多次调用。

function foo(){
    console.log(this.a);
    
}
var a=1
var obj={
    a:1,
    foo:foo
}
var obj2={
    a:2,
    foo:obj
}
obj2.foo.foo()

根据上面的规则是不是foo里的this此时指向的就是obj啊,这个东西不就好比皇帝可以命令将军,而将军命令士兵,士兵是不是直接听将军指挥,而不是皇帝。

屏幕截图 2025-11-27 183624.png

3.3 显式绑定(强制绑定)

当我们想手动控制this的指向时,可以使用显式绑定。

  • fn.call(obj,x,x)显示地将fn里面的this绑定到obj这个对象上,call负责帮fn接受实参数,像下面这样
var obj={
    a:1
}
function foo(x,y){
    console.log(this.a,x+y);
    
}
foo.call(obj,1,2)
  • fn.apply(obj,[x,x])显示地将fn里面的this绑定到obj这个对象上,call以数组的方式接受实参数
var obj={
    a:1
}
function foo(x,y){
    console.log(this.a,x+y);
    
}
foo.apply(obj,[1,2])

-bind不会立即调用函数,而是返回一个绑定了指定this的新函数。

var obj={
    a:1
}
function foo(x,y){
    console.log(this.a,x+y);
    
}
const bar=foo.bind(obj,2,3)
bar()

4. new绑定(构造函数调用)

规则:当使用new关键字调用构造函数时,this会绑定到新创建的实例对象上。


function Person() {

  this.name = '冯总'

}

let p = new Person()

console.log(p);//输出Person { name: '冯总' }

关于return的注意事项
如果构造函数中显式返回一个引用类型(对象、数组、函数),则new操作符会返回这个对象,而不是新创建的实例。

function Person() {
  this.name = '冯总'
  return {a: 1}
}
let p = new Person()
console.log(p);//输出{ a: 1 }

5.箭头函数

箭头函数没有自己的this

箭头函数是ES6的重要特性,它没有自己的this,它的this继承自外层作用域。

看下面这里bar是不是指向foo,虽然foo被obj调用但是还是bar是箭头函数,所以最后输出a就是2

function foo() {
  // this
  var bar = () => {
    this.a = 2
  }
  bar()
}
var obj = {
  a: 1,
  baz: foo
}
obj.baz()
console.log();

结语

理解this的关键在于记住:this的指向取决于函数的调用方式,而不是定义位置。掌握了四大绑定规则和箭头函数的特性,你就能在复杂的代码中游刃有余地处理this指向问题。

希望本文能帮你彻底搞懂JavaScript中的this机制,如果有任何疑问或想分享的经验,欢迎在评论区交流!