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

JavaScript中设置函数自身属性为何不影响函数内部this取值

核心原因

这是JavaScript中this绑定规则和函数对象基础特性导致的:你给step函数对象设置的counter属性,和函数内部this访问的counter根本不在同一个对象上,自然不会互相影响。

具体逻辑拆解

  • 首先记一个非严格模式下最基础的this规则:如果直接用函数名()这种无上下文的裸调用方式执行普通函数,函数内部的this默认指向全局对象——浏览器环境对应window,Node.js环境对应globalThis。
  • 其次要明确:JavaScript里函数本身是一等公民,属于特殊的对象,你写step.counter = 10,本质是给step这个函数对象本身添加自有属性,这个属性存储在函数对象自身的内存空间里,和全局对象没有关联。
  • 回到你的代码,不管你有没有提前给step设置counter属性,step()执行时this.counter读写的都是全局对象上的counter,根本不会触碰step函数对象自身的counter属性。

第二段代码的实际执行流程

  1. 声明step函数,此时全局对象、step函数对象上都不存在counter属性
  2. 执行step.counter = 10:仅给step函数对象添加值为10的counter属性,全局对象上依然没有该属性
  3. 第一次调用step():
    • 函数内this指向全局对象,判断!this.counter为真(全局对象上counter值为undefined,转布尔值为false)
    • 给全局对象挂载counter属性,赋值为0
    • 执行后置自增return this.counter++,返回0,执行完成后全局对象上的counter变为1
  4. 后续两次调用step(),都是在操作全局对象上的counter,依次返回1、2,全程没有访问过step函数对象上值为10的counter,因此输出和未设置该属性时完全一致。

补充验证

如果你希望函数内部访问到自身的counter属性,只需要手动把this绑定到step函数对象即可,比如用call方法:

function step() {
  if (!this.counter) this.counter = 0;
  return this.counter++;
}

step.counter = 10;

console.log(step.call(step)); // 输出10
console.log(step.call(step)); // 输出11
console.log(step.call(step)); // 输出12

额外说明:如果代码运行在严格模式下,裸调用普通函数时this为undefined,此时访问this.counter会直接抛出类型错误,不会出现隐式绑定全局对象的行为,也能帮你更早发现这类指向问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:57:15