es6 的 static 属性属于类本身、所有实例共享且仅一份;声明用 static key = val,访问修改均通过类名或 this.constructor,不可用 this;构造函数中推荐用 this.constructor.count++ 自增;其与实例属性根本区别在于归属和内存位置;并发修改需注意线程安全。

ES6 的 static 属性天然就是所有实例共享的,它不属于某个具体对象,而是绑定在类本身上。只要用 static 关键字声明,这个属性就只有一份,所有实例读取或修改的都是同一个值。
static 属性的声明和访问方式
直接在类体内部用 static 声明即可,不需要写在构造函数里:
- 声明:在类中写
static count = 0;,它会随类定义一起初始化 - 读取:用
ClassName.propertyName,比如Item.count - 修改:同样用
Item.count++或Item.count = 5 - 实例不能通过
this.count访问(会是undefined),必须走类名或this.constructor.count
在构造函数中自动更新共享计数
每次创建新实例时,想让 static 属性自增(比如统计实例数量),就在构造函数里操作它:
- 推荐写法:
this.constructor.count++—— 更安全,避免硬编码类名 - 等效写法:
Item.count++—— 直观,但若类重命名容易出错 - 注意:不要写成
this.count++,这会在实例上新建一个同名普通属性,不共享
静态属性和实例属性的关键区别
理解共享机制,关键看“归属”和“内存位置”:
- 实例属性(如
this.name):每个 new 出来的对象都有一份独立副本 - static 属性:只存在于类上,类加载时就存在,所有实例共用同一内存地址
- 即使没创建任何实例,
Item.count也能直接读取或赋值 - 任意实例或外部代码修改它,其他地方立刻可见最新值
实际使用中的注意事项
共享带来便利,也隐含风险,尤其在多任务环境下:
- 并发修改可能出错:比如多个异步操作同时执行
count++,结果可能少加 - 简单场景可用原生数值;高并发建议用
Atomics或封装成不可变更新逻辑 - 避免在 static 方法里调用
this.xxx—— 静态上下文没有this实例 - 私有化控制:可配合
private static #field(ES2022+)或模块级变量 + getter/setter 限制访问











