当前位置: 首页 > news >正文

@constant 和 @readonly 的区别

在 JSDoc 中,@constant@readonly 都用于表示“值不可变”,但它们的语义、使用场景和官方推荐度有重要区别。以下是详细对比:


✅ 1. @readonly

  • 官方状态:✅ 推荐使用(JSDoc 官方当前标准)
  • 语义
    表示该成员初始化后不应被修改,强调“只读”行为。
  • 典型使用场景
    • 类的属性(最常见):
      class Point {/*** X 坐标(只读)* @readonly*/x = 0;
      }
      
    • 模块级常量(较少见,因 const 已足够):
      /** @readonly */
      const PI = 3.14159;
      
  • 工具支持
    • VS Code、TypeScript、TypeDoc、VitePress 等均良好支持。
    • 在文档中通常显示为 “Readonly” 标签。

📌 关键点@readonly 更侧重于访问控制语义(外部不能改),而非声明方式。


⚠️ 2. @constant

  • 官方状态:❌ 已弃用(deprecated)
  • 语义
    原意是表示“这是一个常量”,但与 JavaScript 的 const 关键字容易混淆。
  • 问题
    • 在早期 JSDoc 中使用,但现代规范已不推荐
    • 官方文档明确指出:Use @readonly instead。
    • 不支持类型参数(如 @constant {number} 是无效语法)。
  • 遗留用法示例(不推荐):
    /** @constant */
    var MAX_SIZE = 100; // 用 var 声明的“逻辑常量”
    

🚫 结论不要使用 @constant,它已被 @readonly 取代。


🔍 核心区别总结

特性 @readonly @constant
官方状态 ✅ 推荐 ❌ 已弃用
语义重点 “只读”(不可修改) “常量”(易与 const 混淆)
典型场景 类属性、配置项 旧代码遗留
是否支持类型 否(需配合 @type 否(且 @constant {T} 无效)
现代工具支持 优秀 有限或忽略

🛠 正确使用示例

✅ 推荐:类属性(最常见)

class Config {/*** API 基础 URL(初始化后不可变)* @type {string}* @readonly*/baseUrl = 'https://api.example.com';
}

✅ 推荐:模块常量(通常无需标签)

// TypeScript:无需 JSDoc,类型和常量性自动推导
/** 默认超时时间(毫秒) */
export const DEFAULT_TIMEOUT = 5000;

❌ 避免:过时写法

/** @constant */        // ← 不要这样写
var VERSION = '1.0.0';

💡 为什么 @readonly 更合理?

JavaScript/TypeScript 中:

  • const 保证变量绑定不可变(不能重新赋值),但对象内容仍可变
    const obj = { x: 1 };
    obj.x = 2; // ✅ 允许!
    
  • @readonly 表达的是设计意图:这个值(无论是否 const不应被外部修改,尤其适用于:
    • 类的公开属性
    • 配置对象字段
    • 库的导出常量(强调“请勿修改”)

✅ 最佳实践建议

  1. 永远不要用 @constant → 改用 @readonly(如果确实需要标注)。
  2. 对于 const 声明的简单值(如字符串、数字)
    • 在 TypeScript 中:完全不需要 JSDoc 标签
    • 在 JavaScript 中:只需描述性注释,除非类型不明显。
  3. 仅在以下情况使用 @readonly
    • 类的属性
    • 复杂对象的只读引用
    • 需要向用户强调“此值不可修改”的 API

📚 官方参考

From JSDoc official docs – @const:
"The @const tag is deprecated. Use @readonly instead."


总结一句话:

忘掉 @constant,用 @readonly 表示只读,而对 const 变量通常什么都不用写。

http://www.jsqmd.com/news/318917/

相关文章:

  • Spring Boot 框架
  • CSS Fonts (字体)
  • Nginx:如何配置基于ip的虚拟主机(总结二)
  • A.每日一题——2976. 转换字符串的最小成本 I
  • Pandas实战技巧,大数据新手入门必学
  • 高通SEE架构深度解析(3): 核心组件从功能模块到安全体系
  • IPD课程系列-产品平台和CCB
  • ollama 调用vlm模型 显存可以省到只用5g左右
  • 高通SEE架构深度解析(2): Sensor HAL层代码实战与ADSP通信
  • 把数字翻译成英文,其实是在考你“结构化思维”
  • python护工预约评价系统管理小程序
  • C++中的职责链模式实战
  • Python多线程与多进程:如何选择?(GIL全局解释器锁详解)
  • 智能标注平台开发:AI应用架构师的必备技能
  • 趣味项目与综合实战
  • 高通SEE架构深度解析(1): 架构原理与核心组件
  • python快递校园帮互助微信小程序设计与实现
  • C++网络编程(Boost.Asio)
  • 摸鱼软件系列:隐藏软件为了方便上班时摸鱼打开某些软件时怕被发现又不想关闭
  • python快餐店微信扫码点餐订餐小程序
  • 构建SpringBoot项目Docker镜像并发布到k8s集群中进行运行
  • 2026年政务服务智能化演进:从被动咨询到“端侧”业务闭环
  • python关于英雄联盟云顶之弈的游戏攻略视频辅助微信小程序
  • python基于小程序的临沂大学非机电动车车辆充电维修管理系统
  • 按照片拍摄日期批量重命名({年}{月}{日}{时}{分}{秒}_{文件名}_{时间戳})工具
  • 全面应用掌握!提示工程架构师带你全面掌握Agentic AI国际化应用技能
  • 使用Python进行PDF文件的处理与操作
  • 提取文件(文件夹)名称小工具目录树文件名字提取BAT脚本加软件
  • 解码分布式节点技术:五大核心特质赋能多行业数字化落地
  • jQuery Mobile 过渡