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

JavaScript三段代码差异解析:变量作用域与this指向问题

全局变量、局部变量与this指向的核心差异解析

先明确两个基础规则:

  • 函数内部访问变量时,局部变量优先级高于全局变量,所以三段代码中第二个console.log(counter)都会输出局部的50,这部分逻辑一致。
  • 差异核心在于this.counter的取值,完全由函数调用时的this指向决定。

第一段代码:普通函数直接调用

var counter = 3;

function example() {
  let counter = 50;
  console.log(this.counter);
  console.log(counter);
};

example();

输出:

Undefined
50
  • 普通函数直接调用时,非严格模式下this指向全局对象(浏览器为window,Node.js为global);但如果代码运行在模块环境(ES模块或Node.js模块)中,用var声明的变量会被限制在模块作用域内,不会挂载到全局对象上,因此this.counter找不到对应属性,输出undefined。
  • 若在普通浏览器全局环境(非模块)中,var counter = 3会自动挂载到window,此时this.counter会输出3——你的输出为undefined,说明代码运行在模块环境中。

第二段代码:用call绑定原始值

var counter = 3;

var example = function() {
  let counter = 50;
  console.log(this.counter);
  console.log(counter);
}

example.call(counter);

输出:

Undefined
50
  • call方法的作用是绑定函数执行时的this,但你传入的counter是原始值3(数字类型)。JavaScript会自动把原始值包装成对应的包装对象(这里是Number对象),但Number对象本身并没有counter属性,因此this.counter输出undefined。
  • 函数内部的局部counter依然优先,所以第二个输出还是50。

第三段代码:用call绑定自定义对象

var counter = 3;

var example = function() {
  let counter = 50;
  console.log(this.counter);
  console.log(counter);
}

example.call({counter});

输出:

3
50
  • 这里的({counter})是ES6对象字面量的简写语法,等同于{counter: counter}——意思是创建一个新对象,其中counter属性的取值等于全局变量counter的值(也就是3)。
  • 用call把这个自定义对象绑定为函数的this,此时this.counter访问的就是该对象的counter属性,因此输出3;局部变量counter依然优先,第二个输出为50。

为什么前两段拿不到全局的3?

  1. 第一段:模块环境下全局变量不会挂载到全局对象,而直接调用函数时this指向全局对象,因此无法通过this.counter访问全局变量。
  2. 第二段:绑定的原始值被包装成包装对象后,该对象没有counter属性,自然无法获取全局的3。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:25:32