全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 8 分钟 ✍️ juanwangdev

JavaScript this 绑定规则

this 是 JavaScript 中最复杂的概念之一,它的值在运行时确定,遵循四条绑定规则。

this 是什么

this 是函数执行上下文的一个属性,在函数调用时确定,而非定义时。

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

foo(); // window(非严格模式)
foo(); // undefined(严格模式)

四条绑定规则

1. 默认绑定

独立调用时,this 指向全局对象(严格模式为 undefined)。

JavaScript
function foo() {
  'use strict';
  console.log(this); // undefined
}

function bar() {
  console.log(this); // window(非严格模式)
}

2. 隐式绑定

函数作为对象方法调用时,this 指向调用者。

JavaScript
const obj = {
  name: 'obj',
  greet: function() {
    console.log(this.name);
  }
};

obj.greet(); // 'obj' - obj 调用 greet

// ⚠️ 隐式丢失
const fn = obj.greet;
fn(); // undefined - 独立调用,默认绑定

3. 显式绑定

使用 call、apply、bind 显式指定 this。

JavaScript
const obj = { name: 'obj' };

function greet(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

// call
greet.call(obj, 'Hello');  // 'Hello, obj'

// apply
greet.apply(obj, ['Hi']);  // 'Hi, obj'

// bind
const boundGreet = greet.bind(obj);
boundGreet('Hey');  // 'Hey, obj'

call/apply/bind 对比

方法执行方式参数形式
call立即执行逐个传递
apply立即执行数组传递
bind返回新函数逐个传递

4. new 绑定

使用 new 调用构造函数时,this 指向新创建的对象。

JavaScript
function Person(name) {
  this.name = name;
}

const p = new Person('Alice');
console.log(p.name); // 'Alice'

// new 执行过程
// 1. 创建空对象
// 2. 设置原型链
// 3. 执行构造函数(this 指向新对象)
// 4. 返回对象(若构造函数无返回值)

绑定优先级

JavaScript
new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定

优先级示例

JavaScript
function foo(something) {
  this.a = something;
}

const obj = {};

// 显式绑定
const boundFoo = foo.bind(obj);
boundFoo(1);
console.log(obj.a); // 1

// new 绑定优先级更高
const bar = new boundFoo(2);
console.log(obj.a); // 1(未改变)
console.log(bar.a); // 2(new 创建了新对象)

箭头函数的 this

词法绑定

箭头函数没有自己的 this,继承外层作用域的 this。

JavaScript
const obj = {
  name: 'obj',
  greet: function() {
    const arrow = () => {
      console.log(this.name); // 'obj' - 继承自 greet
    };
    arrow();
  }
};

obj.greet();

解决回调中的 this 问题

JavaScript
const obj = {
  name: 'obj',
  greet: function() {
    // ❌ 普通函数丢失 this
    setTimeout(function() {
      console.log(this.name); // undefined
    }, 100);

    // ✅ 箭头函数保留 this
    setTimeout(() => {
      console.log(this.name); // 'obj'
    }, 100);

    // ✅ bind 显式绑定
    setTimeout(function() {
      console.log(this.name);
    }.bind(this), 100);
  }
};

箭头函数不能改变 this

JavaScript
const arrow = () => {
  console.log(this);
};

const obj = { name: 'obj' };

arrow.call(obj);  // 仍是外层 this
arrow.apply(obj); // 仍是外层 this
arrow.bind(obj)();// 仍是外层 this

new arrow(); // TypeError: arrow is not a constructor

常见陷阱

1. 隐式丢失

JavaScript
const obj = {
  name: 'obj',
  greet: function() {
    console.log(this.name);
  }
};

// 赋值后丢失绑定
const fn = obj.greet;
fn(); // undefined

// 回调中丢失
function doSomething(callback) {
  callback();
}
doSomething(obj.greet); // undefined

2. 对象引用链

JavaScript
const obj = {
  name: 'obj',
  inner: {
    name: 'inner',
    greet: function() {
      console.log(this.name);
    }
  }
};

obj.inner.greet(); // 'inner' - 最近的对象引用

3. 原型链上的 this

JavaScript
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(this.name);
};

const p = new Person('Alice');
p.greet(); // 'Alice' - this 是 p,不是 prototype

4. 类中的 this

text
class Counter {
  constructor() {
    this.count = 0;
  }

  increment() {
    this.count++;
  }

  start() {
    // ❌ 丢失 this
    // setInterval(this.increment, 1000);

    // ✅ 箭头函数
    setInterval(() => this.increment(), 1000);

    // ✅ bind
    // setInterval(this.increment.bind(this), 1000);
  }
}

判断 this 的步骤

text
1. 函数是否 new 调用? → this 是新对象
2. 函数是否 call/apply/bind? → this 是绑定的对象
3. 函数是否作为方法调用? → this 是调用对象
4. 是否是箭头函数? → this 是外层 this
5. 默认绑定 → 全局对象(严格模式 undefined)

要点总结

规则this 指向优先级
默认绑定全局/undefined最低
隐式绑定调用对象
显式绑定指定对象
new 绑定新对象最高
箭头函数词法作用域特殊
  • this 在调用时确定,非定义时
  • 箭头函数没有 this,继承外层
  • 优先级:new > 显式 > 隐式 > 默认
  • 注意隐式丢失,使用 bind 或箭头函数修复

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript JIT 编译优化
下一篇 → JavaScript 事件循环与宏任务/微任务
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库