You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中this关键字绑定规则疑问:两段示例代码执行结果求解

核心前置误区纠正

this 的属性查找和JS的词法作用域是完全独立的两套规则,不存在互相替代的关系,你遇到的问题本质是混淆了「this指向的对象的属性查找」和「普通变量的词法作用域查找」。


示例1执行逻辑解释

function foo() { 
    console.log(this.bar)
}
var bar = "bar1"
foo();

非严格模式下,没有任何前缀的独立函数调用(foo())的this默认绑定到全局对象(浏览器环境是window,Node.js环境是globalThis)。
你用var在全局作用域声明的变量,会自动成为全局对象的属性,相当于window.bar = "bar1",因此this.bar等价于window.bar,最终输出bar1。

补充:如果是严格模式,独立函数调用的this会是undefined,运行这段代码会直接抛出类型错误。如果把var bar改成let bar/const bar,全局声明不会挂载到全局对象上,也会输出undefined。


示例2执行逻辑解释

function foo() { 
    console.log(this.bar)
}
var o2 = {foo:foo}
console.log(o2.foo())

当函数作为对象的属性被调用时(o2.foo()),this会隐式绑定到调用它的前置对象o2。
你的o2对象只定义了foo属性,没有定义bar属性,this.bar等价于o2.bar,自然输出undefined。
另外你这段代码实际运行会输出两次undefined:第一次是foo内部的console.log输出的o2.bar的值,第二次是外层console.log输出的foo函数的返回值(foo没有主动return,默认返回undefined)。


设计逻辑说明

this的设计初衷是实现「函数上下文的动态绑定」,让同一个函数可以被多个对象复用,不用硬编码绑定死上下文,大幅减少重复代码,比如:

function printName() {
  console.log(this.username)
}
const userA = {username: '小王', print: printName}
const userB = {username: '小李', print: printName}
userA.print() // 输出小王
userB.print() // 输出小李

如果没有this,你需要给每个对象单独写一遍相同的printName函数,或者手动把对象作为参数传入函数,代码冗余度会高很多。


针对你的疑问的明确回答

  • 不是调用涉及对象就不采用普通作用域规则:普通作用域规则管的是普通变量的查找,this的属性查找只负责this这个特殊关键字指向的对象的属性查询,两者互不影响。比如你把示例2的foo内部代码改成console.log(bar),不管你用什么对象调用foo,都会走词法作用域查找,最终输出全局的bar1。

内容的提问来源于stack exchange,提问作者ArunM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:15:03