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

JavaScript中this关键字作用域理解困惑及代码疑问

搞懂JavaScript中this的全局绑定问题

嘿,我完全理解你在啃JavaScript的this关键字时有多懵——这玩意儿绝对是新手入门的“拦路虎”之一!先帮你拆解一下你提到的这段代码,再说说为什么讲师说这是不良实践,以及怎么避免踩坑。

首先先把你的代码格式化一下,方便分析:

var person = "roht" 
function whatIsThis() { 
  return this 
  console.log(this) // 注意:这里的console不会执行,因为前面已经return了
} 
function variable (){ 
  this.person = "max" 
} 
variable() 
console.log(person) 
whatIsThis()

为什么this.person会绑定到全局对象?

在非严格模式下,直接调用一个普通函数(既不是作为对象的方法调用,也没用new、call/apply/bind这类方式),函数内部的this会自动绑定到全局对象:

  • 在浏览器环境里,全局对象是window;在Node.js环境里是global。
  • 你一开始用var person = "roht"声明的变量,本身就是全局对象的一个属性(因为var声明的全局变量会挂载到全局对象上)。所以当你调用variable()时,this.person = "max"本质上是在修改全局对象的person属性,自然会覆盖你一开始的"roht",最后console.log(person)就会输出"max"。

另外提一句:whatIsThis()里的return this会直接返回全局对象,后面的console.log(this)根本不会执行哦。

为什么这是不良实践?

  • 污染全局命名空间:全局对象上的属性是所有脚本共享的,如果其他地方也定义了person变量,就会互相覆盖,排查bug的时候会头大到怀疑人生。
  • 代码可读性差:别人看代码时,很难一眼看出person是在哪里被修改的,维护起来成本极高。
  • 不可预测性:如果后续代码不小心开启了严格模式('use strict'),普通函数调用时this会变成undefined,这时候this.person = "max"会直接抛出错误,代码直接崩掉。

怎么写才是正确的姿势?

给你几个替代方案,按需选择:

1. 用局部作用域隔离变量

用立即执行函数表达式(IIFE)把代码包裹起来,避免污染全局:

(function() {
  // 用let/const代替var,避免变量提升和全局挂载问题
  let person = "roht";
  function changePersonName() {
    // 直接修改局部变量,根本不需要this
    person = "max";
  }
  changePersonName();
  console.log(person); // 输出 "max"
})();

2. 用对象/类封装数据和行为

如果是要处理“人物”这类有属性和行为的逻辑,用对象或者类更合理,这时候this的指向也更清晰:

// 用普通对象
const person = {
  name: "roht",
  changeName(newName) {
    // 这里的this指向person对象本身
    this.name = newName;
  }
};
person.changeName("max");
console.log(person.name); // 输出 "max"

// 用ES6类(更适合复杂的实例化场景)
class Person {
  constructor(name) {
    this.name = name;
  }
  changeName(newName) {
    this.name = newName;
  }
}
const myPerson = new Person("roht");
myPerson.changeName("max");
console.log(myPerson.name); // 输出 "max"

3. 用闭包或者参数传递

如果只是要在函数里修改变量,也可以用闭包或者把变量作为参数传递:

function createNameChanger(initialName) {
  let name = initialName;
  return function(newName) {
    name = newName;
    return name;
  };
}
const changeName = createNameChanger("roht");
changeName("max");
console.log(changeName()); // 输出 "max"

最后再帮你梳理下this的核心绑定规则

记住这几个场景,下次遇到this就不会慌了:

  • 作为对象方法调用:obj.func() → this指向obj
  • 用new调用构造函数:new Func() → this指向新创建的实例对象
  • 用call/apply/bind显式绑定:func.call(obj) → this指向obj
  • 普通函数调用(非严格模式):func() → this指向全局对象;严格模式下是undefined

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:32:52