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

JavaScript工厂函数公共属性存储位置及访问方法咨询

问题根因

你代码里的counter属性实际存储在全局对象上(浏览器环境为window,Node.js环境为globalThis),并没有挂载到foo函数对象上。

  • 普通函数直接调用时(没有用new、没有用call/apply/bind绑定this指向),非严格模式下this默认指向全局对象,你代码中所有this.counter的读写操作,实际都是在操作全局对象的counter属性。
  • 这也是为什么连续调用foo()时计数会递增,但直接访问foo.counter会返回undefined——foo函数对象本身从始至终都没有被添加过counter属性。

补充:如果代码运行在严格模式下,普通函数调用的this为undefined,你当前的代码会直接抛出Cannot set properties of undefined的错误。

正确实现方案

要实现统计已创建对象总数的需求,有两种常见实现方式:

方案1:直接将计数器挂载到函数对象上

函数在JS中是一等公民,本身就是对象,可以直接挂载属性,访问时直接读函数对象的对应属性即可:

function foo(){
    // 直接操作foo函数对象上的counter属性
    foo.counter = foo.counter ? foo.counter + 1 : 1;
    // 工厂函数逻辑:返回自定义的实例对象
    const instance = {};
    console.log(foo.counter);
    return instance;
}

let a = foo(); // 输出1
let b = foo(); // 输出2
console.log(foo.counter); // 正确返回2

方案2:闭包实现私有计数器

如果不希望外部直接修改计数器的值,可以用闭包生成私有变量,仅暴露必要的读取接口:

const foo = (function() {
    // 私有计数器,外部作用域无法直接访问
    let createdCount = 0;
    return function() {
        createdCount++;
        console.log(createdCount);
        // 可选:给实例暴露读取计数的方法
        return {
            getTotalCreated: () => createdCount
        };
    }
})();

let a = foo(); // 输出1
let b = foo(); // 输出2
console.log(a.getTotalCreated()); // 返回2
// 直接访问外部的createdCount会报变量未定义的错误,无法随意篡改计数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:34:46