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

各层级定义var变量得到非预期结果,为何JS代码输出是4而非3

JavaScript代码输出4而非3的原因
var x=4,
obj={
    x: 3,
    bar:function(){
        var x = 2;
        setTimeout(function(){
            var x=1;
            console.log(this.x);
        },1000);
    }
}
obj.bar();

输出结果为4的核心原因是普通函数作为setTimeout回调时的默认this绑定规则,和局部变量作用域无关,具体逻辑拆解如下:

  • 非严格模式下,setTimeout的普通函数回调执行时,this默认绑定到全局对象:浏览器环境为window,Node.js环境为globalThis。
  • 代码执行逻辑梳理:
    1. 顶层用var声明的x=4会自动成为全局对象的属性,即window.x = 4。
    2. obj.bar()调用时,bar函数内部的this确实指向obj,此时this.x为3,但这个this不会自动传递给内部的setTimeout回调。
    3. setTimeout的回调是独立执行的普通函数,它内部的this指向全局对象,因此console.log(this.x)读取的是全局对象的x属性,也就是4。
    4. bar函数内的var x=2、回调内的var x=1都是函数局部作用域的变量,和this.x完全不相关:this.x读取的是this绑定对象的属性,不是当前作用域的局部变量。
  • 如果要让输出为3,只要修改回调的this绑定即可,常见方案两种:
    1. 改用箭头函数作为回调,箭头函数会继承外层执行上下文的this:
    setTimeout(() => {
      var x=1;
      console.log(this.x); // 继承bar函数的this指向obj,输出3
    }, 1000);
    
    1. 用bind手动绑定回调的this指向:
    setTimeout(function(){
      var x=1;
      console.log(this.x); // 手动绑定this为obj,输出3
    }.bind(obj), 1000);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:48:02