JavaScript 中 this 指向的判定规则与优先级

作者:半夏时间:2026-10-22 08:31:38浏览:200

本文详细解析 JavaScript 中 this 关键字的四种核心绑定规则:new 构造函数、apply/call/bind 显式绑定、对象方法隐式绑定以及默认全局绑定。重点说明当多条规则冲突时的高优先级判定逻辑,并特别阐述 ES2015 箭头函数忽略常规规则、继承词法作用域 this 的特性。

JavaScript this 指向判定规则

确定函数内部 this 指向的核心依据。

判断 this 指向并不复杂,核心原则是依据函数被调用的位置(调用栈)来动态确定。具体的判定逻辑遵循以下优先级顺序的规则。

判定规则

1. 使用 new 关键字调用函数时,函数内部的 this 指向新创建的实例对象。


function ConstructorExample() {
  console.log(this);
  this.value = 10;
  console.log(this);
}
new ConstructorExample();
// -> {}
// -> { value: 10 }

2. 使用 apply、call 或 bind 方法调用函数时,函数内部的 this 指向作为参数传入的那个对象。


function fn() {
  console.log(this);
}
var obj = {
  value: 5
};
var boundFn = fn.bind(obj);
boundFn();   // -> { value: 5 }
fn.call(obj); // -> { value: 5 }
fn.apply(obj); // -> { value: 5 }

3. 函数作为对象方法调用时(即使用点符号访问),this 指向调用该方法的对象。简而言之,当点符号左侧存在对象时,this 即指向该左侧对象。


var obj = {
  value: 5,
  printThis: function() {
    console.log(this);
  }
};
obj.printThis(); // -> { value: 5, printThis: ƒ }

4. 函数作为普通函数独立调用时(即不满足上述任何条件),this 指向全局对象。在浏览器环境中,全局对象即为 window。


function fn() {
  console.log(this);
}
// 如果在浏览器里调用:
fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

需注意,此规则与规则 3 本质一致,区别在于未显式声明为方法的函数会自动成为全局对象 window 的属性。因此,调用 fn() 实际上等同于调用 window.fn(),此时 this 指向 window。


console.log(fn === window.fn); // -> true

5. 当多条规则同时适用时,优先级更高的规则将决定 this 的最终指向。

6. 对于 ES2015 引入的箭头函数,它将忽略上述所有常规规则。箭头函数在定义时捕获其所在词法作用域的 this 值。判断箭头函数内的 this,只需查看定义该箭头函数的外层作用域中 this 的值,箭头函数内的 this 与其保持一致。


const obj = {
  value: 'abc',
  createArrowFn: function() {
    return () => console.log(this);
  }
};
const arrowFn = obj.createArrowFn();
arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }

回顾规则 3,当调用 obj.createArrowFn() 时,createArrowFn 内部的 this 指向 obj,因为这是方法调用。因此,obj 会被绑定到 arrowFn 内部的 this 上。若在全局作用域直接创建箭头函数,其 this 值将指向 window。

this 指向规则的实际应用

规则应用示例

通过以下代码示例来验证这些规则,尝试分析不同函数调用方式下 this 的具体指向。

判定具体适用的规则


var obj = {
  value: 'hi',
  printThis: function() {
    console.log(this);
  }
};
var print = obj.printThis;
obj.printThis(); // -> {value: "hi", printThis: ƒ}
print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

obj.printThis() 符合规则 3,属于方法调用。而 print() 符合规则 4,属于普通函数调用。对于 print(),调用时未使用 new、bind/call/apply 或点符号,因此对应规则 4,this 指向全局对象 window。

多规则冲突时的处理

当多条规则同时适用时,应遵循列表中优先级更高的规则。


var obj1 = {
  value: 'hi',
  print: function() {
    console.log(this);
  },
};
var obj2 = { value: 17 };

若规则 2(显式绑定)与规则 3(隐式绑定)同时适用,规则 2 优先级更高。


obj1.print.call(obj2); // -> { value: 17 }

若规则 1(new 绑定)与规则 3(隐式绑定)同时适用,规则 1 优先级更高。


new obj1.print(); // -> {}

第三方库对 this 绑定的影响

第三方库的影响

部分库可能会故意将 this 绑定到特定函数上,通常会将最有用的值绑定到 this。例如,jQuery 在事件回调中将 this 绑定到 DOM 元素上。如果某个库的 this 行为不符合上述常规规则,请查阅该库文档,其很可能使用了 bind 方法进行了特殊绑定。

总结

以上内容介绍了 JavaScript 中 this 指向的基本规则,希望能为读者提供帮助。如有任何疑问,欢迎留言交流,我们将及时回复。感谢对本站的支持!

作者最新文章