javascript
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJavaScript
JavaScript
Specification
规范说明
The words , , , , , , , , , and are interpreted as described in RFC 2119.
MUSTMUST NOTREQUIREDSHALLSHALL NOTSHOULDSHOULD NOTRECOMMENDEDMAYOPTIONALClarity is the highest JavaScript virtue. If your code requires a comment to explain its control flow, rewrite it.
JavaScript rewards explicit, readable code. You SHOULD prefer boring patterns that are easy to understand over clever
tricks that save characters.
本文中的、、、、、、、、和均按照RFC 2119中的定义解释。
MUSTMUST NOTREQUIREDSHALLSHALL NOTSHOULDSHOULD NOTRECOMMENDEDMAYOPTIONAL清晰是JavaScript的最高准则。如果你的代码需要注释来解释控制流,请重写代码。
JavaScript推崇明确、可读的代码。你应当优先选择易于理解的常规写法,而非节省字符的巧妙技巧。
References
参考文档
- Functions, closures, composition → — Arrow function examples, closure patterns, early return, parameter destructuring
references/functions.md - Async patterns, error handling, concurrency → — Promise.all/race/any examples, cancellation, custom error classes, for-await
references/async.md - Objects, arrays, iteration, Map/Set → — Iteration decision table, destructuring patterns, immutable updates, generators
references/objects-and-arrays.md - ES modules, imports, barrel files → — Import ordering, barrel file rationale, directory import pitfalls, dynamic imports
references/modules.md - JSDoc typing, full tag catalog → — Full tag reference (@callback, @template, @enum), type assertions, class modifiers
references/jsdoc.md - General JS idioms and edge cases → — Variable/naming examples, equality coercion table, modern syntax patterns
references/idioms.md
- 函数、闭包、组合 → — 箭头函数示例、闭包模式、提前返回、参数解构
references/functions.md - 异步模式、错误处理、并发 → — Promise.all/race/any示例、取消操作、自定义错误类、for-await
references/async.md - 对象、数组、迭代、Map/Set → — 迭代决策表、解构模式、不可变更新、生成器
references/objects-and-arrays.md - ES模块、导入、桶文件 → — 导入排序、桶文件原理、目录导入陷阱、动态导入
references/modules.md - JSDoc类型、完整标签目录 → — 完整标签参考(@callback、@template、@enum)、类型断言、类修饰符
references/jsdoc.md - 通用JS惯用写法与边界情况 → — 变量/命名示例、相等强制转换表、现代语法模式
references/idioms.md
Requests
工具要求
- You are RECOMMENDED to use as the package manager unless told otherwise.
bun
- 除非另有说明,推荐使用作为包管理器。
bun
Variables and Declarations
变量与声明
- by default. You SHOULD use
constonly when reassignment is required. You MUST NOT uselet.var - prevents reassignment, not mutation. Objects and arrays declared with
constcan still be mutated.const - Block scope only. /
letare block-scoped;constis function-scoped and hoists — this causes bugs in loops and conditionals.var - One declaration per line. You MUST NOT chain .
const a = 1, b = 2 - Group declarations. first, then
const.let
- 默认使用。仅当需要重新赋值时才应使用
const。严禁使用let。var - 阻止重赋值,但不阻止突变。用
const声明的对象和数组仍然可以被修改。const - 仅使用块级作用域。/
let是块级作用域;const是函数级作用域且存在变量提升——这会在循环和条件语句中引发bug。var - 每行一个声明。严禁链式声明。
const a = 1, b = 2 - 分组声明。先声明,再声明
const。let
Naming
命名规范
| Entity | Style | Examples |
|---|---|---|
| Variables, functions | camelCase | |
| Classes, constructors | PascalCase | |
| True compile-time constants | SCREAMING_SNAKE_CASE | |
| Private fields/methods | | |
| Booleans | | |
| File names | kebab-case or camelCase | |
- SCREAMING_SNAKE_CASE is for true constants only — values known at compile time, never computed at runtime. A variable holding a function return value uses camelCase.
- Descriptive names. not
userCount. Short names (n,i) only in tiny scopes (loop indices, simple arrow callbacks).x - Accepted abbreviations: ,
url,id,err,ctx,req— universally understood. Avoid all others.res - No redundant context. not
car.make.car.carMake - Consistent vocabulary. Use the same word for the same concept throughout a codebase — everywhere, not
getUser()/getUserInfo()/getClientData().getCustomerRecord()
| 实体类型 | 命名风格 | 示例 |
|---|---|---|
| 变量、函数 | camelCase(小驼峰) | |
| 类、构造函数 | PascalCase(大驼峰) | |
| 真正的编译时常量 | SCREAMING_SNAKE_CASE(全大写下划线) | |
| 私有字段/方法 | | |
| 布尔值 | | |
| 文件名 | kebab-case(短横线)或camelCase | |
- SCREAMING_SNAKE_CASE仅用于真正的常量——编译时已知的值,运行时绝不计算。存储函数返回值的变量使用camelCase。
- 使用描述性名称。用而非
userCount。仅在极小作用域(循环索引、简单箭头回调)中使用短名称(n、i)。x - 可接受的缩写:、
url、id、err、ctx、req——这些是通用理解的缩写。避免其他所有缩写。res - 无冗余上下文。用而非
car.make。car.carMake - 词汇保持一致。在整个代码库中对同一概念使用相同词汇——全程使用,而非
getUser()/getUserInfo()/getClientData()。getCustomerRecord()
Equality and Safety
相等性与安全性
- Equality MUST use and
===. You MUST NOT use!==except for==(checks bothvalue == nullandnull).undefined - over
??for defaults —||treats||,0,""as falsy.false - for optional access. Don't overuse — missing data you expect SHOULD throw, not silently return
?..undefined - Know the falsy values: ,
false,0,-0,0n,"",null,undefined. Everything else is truthy, includingNaN,[], and{}."0"
- 相等性必须使用和
===。严禁使用!==,除非是==(同时检查value == null和null)。undefined - 默认值使用而非
??——||会将||、0、""视为假值。false - 可选访问使用。不要过度使用——预期存在的数据缺失时应当抛出错误,而非静默返回
?.。undefined - 了解假值:、
false、0、-0、0n、""、null、undefined。其他所有值均为真值,包括NaN、[]和{}。"0"
Ternary Operator
三元运算符
-
One-liners or split-per-branch only. Ternaries are acceptable in two forms:js
// OK — fits on one line const label = isActive ? 'Active' : 'Inactive' // OK — each branch on its own line const label = isActive ? buildActiveLabel(user) : buildInactiveLabel(user)Any ternary that doesn't fit one of these two patterns MUST be rewritten as/ifor early return.else -
Nested ternaries MUST NOT be used. Use/
if, early returns, or a lookup object.else
-
仅允许单行或按分支拆分的写法。三元表达式仅接受以下两种形式:js
// 允许——单行展示 const label = isActive ? 'Active' : 'Inactive' // 允许——每个分支单独一行 const label = isActive ? buildActiveLabel(user) : buildInactiveLabel(user)任何不符合这两种模式的三元表达式必须重写为/if或提前返回。else -
严禁使用嵌套三元表达式。使用/
if、提前返回或查找对象替代。else
Modern Syntax
现代语法
- Template literals for string interpolation: . Don't use template literals for strings without interpolation — use plain quotes.
`Hello, ${name}` - Spread for copies: and
{ ...obj }. You SHOULD NOT use[...arr].Object.assign - Rest parameters to collect remaining: .
const { id, ...rest } = user - Shorthand properties: not
{ name, age }. Group shorthand properties at the top of object literals.{ name: name, age: age } - Computed property names: ${key}Date
{ [key]: value, [.]: new Date() } - Logical assignment operators: (assign if nullish),
opts.timeout ??= 5000(assign if falsy),opts.name ||= "default"(assign if truthy).opts.handler &&= wrap(opts.handler)
- 字符串插值使用模板字面量:。不要对无插值的字符串使用模板字面量——使用普通引号。
`Hello, ${name}` - 复制使用扩展运算符:和
{ ...obj }。不应使用[...arr]。Object.assign - 剩余参数收集剩余值:。
const { id, ...rest } = user - 属性简写:而非
{ name, age }。将简写属性放在对象字面量的顶部。{ name: name, age: age } - 计算属性名:${key}Date
{ [key]: value, [。]: new Date() } - 逻辑赋值运算符:(当值为nullish时赋值)、
opts.timeout ??= 5000(当值为假值时赋值)、opts.name ||= "default"(当值为真值时赋值)。opts.handler &&= wrap(opts.handler)
Functions
函数
- Arrow functions for callbacks and anonymous functions. Use function declarations only when hoisting or binding is needed.
this - Prefer parentheses around arrow function parameters even for single params — smaller diffs when adding/removing parameters.
- Implicit return for single expressions (no braces). Explicit return (braces) for multi-statement bodies.
- Arrow functions capture lexical — they do NOT have their own
this. You MUST NOT use arrow functions as object methods or on prototypes.this - Destructured options for 3+ parameters. Self-documenting and order-independent.
- Default parameters over or manual checks. Defaults are evaluated left-to-right and can reference earlier params.
|| - Rest parameters over object.
argumentsis array-like, not a real Array.arguments - Early return. Guard clauses first, happy path flat. Reduce nesting.
- One function, one job. If the name contains "and", split it.
- Keep functions under ~30 lines. Extract helpers. Use composition over complex branching.
- Prefer pure functions (same input = same output, no side effects). Isolate side effects (DOM, network, logging) — don't hide them inside data transformations.
- Closures retain references to outer variables, not copies. Be cautious with large objects captured unintentionally — they won't be garbage collected until the closure is released.
- 回调和匿名函数使用箭头函数。仅当需要变量提升或绑定时才使用函数声明。
this - 箭头函数参数优先加括号——即使是单个参数,这样在添加/移除参数时差异更小。
- 单表达式使用隐式返回(无大括号)。多语句体使用显式返回(带大括号)。
- 箭头函数捕获词法作用域的——它们没有自己的
this。严禁将箭头函数用作对象方法或原型方法。this - 参数数量≥3时使用解构选项。自文档化且参数顺序无关。
- 默认参数优于或手动检查。默认值从左到右求值,可引用之前的参数。
|| - 剩余参数优于对象。
arguments是类数组,而非真正的数组。arguments - 提前返回。先写守卫子句,让主逻辑保持扁平化。减少嵌套。
- 单一职责。如果函数名包含"and",则拆分它。
- 函数长度控制在~30行以内。提取辅助函数。优先使用组合而非复杂分支。
- 优先使用纯函数(相同输入=相同输出,无副作用)。隔离副作用(DOM操作、网络请求、日志)——不要隐藏在数据转换中。
- 闭包保留对外部变量的引用,而非副本。谨慎处理意外捕获的大型对象——在闭包释放前它们不会被垃圾回收。
Async
异步处理
- /
asyncoverawaitchains for sequential operations..then() - Promises MUST be awaited or explicitly handled. Missing = floating promise = silent failures.
await - only inside
return awaitblocks where you need to catch the awaited error. Otherwise justtry— no need forreturn promisewrapper.async - for independent parallel work. Rejects on first rejection.
Promise.all - when all results matter regardless of individual failures.
Promise.allSettled - for timeouts.
Promise.racefor fallbacks (rejects only when ALL reject).Promise.any - Avoid sequential awaits in loops. Use for parallel. Use a concurrency limiter (e.g.
Promise.all(items.map(...))) for large arrays.p-map - You MUST throw objects, not strings or plain objects — strings lose stack traces.
Error - Use when checking whether a caught value is an
Error.isError(error). Do not useError.error instanceof Error - Custom error classes when callers need to distinguish errors: extend , set
Error, add context properties.this.name - You MUST NOT swallow errors. Every MUST handle, rethrow, or report. Empty
catchblocks hide bugs.catchalone is not handling.console.log(err) - Let errors propagate to a top-level handler when possible. Don't wrap every in
await/try— only where you need to handle at that level.catch - Attach to non-awaited promise chains. Unhandled rejections crash Node.js. Fire-and-forget:
.catch().fetchData().catch(reportError) - You SHOULD use only to wrap callback-based APIs. Most async code SHOULD compose existing promises with
new Promise()/async.await - for cancellable async operations: pass
AbortControllerto{ signal }and other APIs.fetch - for async iterables (streams, async generators).
for await...of
- 顺序操作优先使用/
async而非await链。.then() - Promise必须被await或显式处理。遗漏会导致浮动Promise,进而引发静默失败。
await - 仅在块内使用
try——此时需要捕获await的错误。否则直接return await即可,无需return promise包装。async - ****用于独立的并行任务。第一个Promise拒绝时整体拒绝。
Promise.all - ****用于无论单个任务是否失败,都需要所有结果的场景。
Promise.allSettled - **用于超时场景。
Promise.race**用于降级场景(仅当所有Promise都拒绝时才拒绝)。Promise.any - 避免在循环中顺序await。使用实现并行。处理大型数组时使用并发限制器(如
Promise.all(items.map(...)))。p-map - 必须抛出对象,而非字符串或普通对象——字符串会丢失堆栈跟踪。
Error - 检查捕获值是否为Error时使用。不要使用
Error.isError(error)。error instanceof Error - 当调用者需要区分错误时使用自定义错误类——继承,设置
Error,添加上下文属性。this.name - 严禁吞掉错误。每个必须处理、重新抛出或上报。空
catch块会隐藏bug。仅catch不视为处理错误。console.log(err) - 尽可能让错误传播到顶层处理器。不要给每个都包裹
await/try——仅在需要在当前层级处理时使用。catch - 非await的Promise链必须附加。未处理的拒绝会导致Node.js崩溃。即发即弃场景:
.catch()。fetchData().catch(reportError) - 仅在包装基于回调的API时使用。大多数异步代码应当通过
new Promise()/async组合现有Promise。await - ****用于可取消的异步操作:将
AbortController传递给{ signal }和其他API。fetch - ****用于异步可迭代对象(流、异步生成器)。
for await...of
Modules
模块
- ES modules are REQUIRED for new code. /
importfor all new code. CommonJS (export) is legacy — use only when runtime requires it.require - Named exports over default exports. Default exports cause inconsistent naming across importers. Exception: default exports acceptable when REQUIRED by framework convention (Next.js pages, Remix routes).
- Don't export mutable bindings. Export accessor functions instead:
letnotexport function getCount().export let count - Imports at the top, grouped with blank lines: built-in (), external (
node:fs), internal (express)../utils - Import paths MUST include file extensions — , not
"./user.js". Extensionless imports vary across runtimes."./user" - No directory imports. Import from the file directly, not from a folder that resolves to .
index.js - No barrel files in subdirectories. re-exports create indirection and hurt tree-shaking. Acceptable only as a standalone package entry point where the runtime can enforce the boundary via
index.jspackage.json.exports - No circular dependencies. Extract shared code to a third module, merge tightly coupled modules, or use dependency injection.
- No wildcard re-exports. Explicit re-exports only — wildcards bypass tree-shaking.
- Merge imports from the same module into a single statement.
- Namespace imports () for large modules (5+ items). Prefer named imports when importing fewer than ~5 items.
import * as dateFns - Dynamic imports () for code splitting and lazy loading: routes loaded on navigation, large conditional dependencies, feature flags.
import() - One concern per module. If a module exports unrelated functionality, split it.
- Side-effect imports () SHOULD be rare. Document why.
import "./polyfill.js"
- 新代码必须使用ES模块。所有新代码使用/
import。CommonJS(export)属于遗留语法——仅当运行环境要求时才使用。require - 命名导出优于默认导出。默认导出会导致导入者命名不一致。例外:当框架约定要求时可使用默认导出(Next.js页面、Remix路由)。
- 不要导出可变的绑定。改为导出访问器函数:
let而非export function getCount()。export let count - 导入语句放在顶部,按空行分组:内置模块()、外部模块(
node:fs)、内部模块(express)。./utils - 导入路径必须包含文件扩展名——,而非
"./user.js"。无扩展名导入在不同运行环境中表现不同。"./user" - 不要使用目录导入。直接从文件导入,而非从解析到的文件夹导入。
index.js - 子目录中不要使用桶文件。重导出会增加间接性并影响摇树优化。仅在独立包的入口点允许使用,此时运行时可通过
index.js的package.json字段 enforce 边界。exports - 不要存在循环依赖。将共享代码提取到第三个模块,合并紧密耦合的模块,或使用依赖注入。
- 不要使用通配符重导出。仅使用显式重导出——通配符会绕过摇树优化。
- 将同一模块的导入合并为单个语句。
- 大型模块(≥5个导入项)使用命名空间导入()。导入项少于~5个时优先使用命名导入。
import * as dateFns - 动态导入()用于代码分割和懒加载:导航时加载路由、大型条件依赖、功能开关。
import() - 每个模块单一职责。如果一个模块导出不相关的功能,拆分它。
- 副作用导入()应当尽量少用。并说明原因。
import "./polyfill.js"
Objects and Arrays
对象与数组
- Literal syntax. and
{}, never[]/new Object().new Array() - Use method shorthand on objects: not
greet() { }.greet: function() { } - Spread for copies. and
{ ...obj }. Prefer over[...arr].Object.assign - Destructure to extract properties. Prefer parameter destructuring.
- Dot notation for static properties, brackets for dynamic: vs
user.name.user[dynamicKey] - instead of
Object.hasOwn(obj, key).obj.hasOwnProperty(key) - Functional array methods (,
map,filter,find,some,every,flatMap) over imperative loops for data transformation.reduce - Always return in ,
map,filtercallbacks.reduce - for array-like objects (not spread).
Array.from(arrayLike)instead ofArray.from(iterable, mapFn)— avoids intermediate array.[...iterable].map(mapFn) - Don't mutate inputs. Return new objects/arrays. Immutable update patterns: add , remove
[...arr, item], updatearr.filter(...).arr.map(...) - for side-effect loops. Never
for...ofon arrays.for...in - Return objects for multiple values, not arrays — callers don't depend on order.
- Built-in prototypes MUST NOT be extended (,
Array.prototype). Use utility functions or subclasses.Object.prototype
Prefer for side-effect loops, methods (, , , , ,
) for data transforms, for index-needed loops. See
for the full iteration decision table.
for...ofArray.prototype.map.filter.reduce.find.some.everyforreferences/objects-and-arrays.mdUse when keys aren't strings or are user-provided (avoids prototype pollution). Use for dedup
(). Use generators () for lazy sequences and deferred computation.
MapSet[...new Set(items)]function*- 使用字面量语法。和
{},绝不使用[]/new Object()。new Array() - 对象上使用方法简写:而非
greet() { }。greet: function() { } - 复制使用扩展运算符。和
{ ...obj }。优先于[...arr]。Object.assign - 解构提取属性。优先使用参数解构。
- 静态属性使用点表示法,动态属性使用方括号:vs
user.name。user[dynamicKey] - 使用替代
Object.hasOwn(obj, key)。obj.hasOwnProperty(key) - 数据转换优先使用函数式数组方法(、
map、filter、find、some、every、flatMap)而非命令式循环。reduce - 、
map、filter的回调必须始终返回值。reduce - 类数组对象使用(而非扩展运算符)。
Array.from(arrayLike)替代Array.from(iterable, mapFn)——避免中间数组。[...iterable].map(mapFn) - 不要修改输入。返回新的对象/数组。不可变更新模式:添加、删除
[...arr, item]、更新arr.filter(...)。arr.map(...) - 副作用循环使用。绝不使用
for...of遍历数组。for...in - 多值返回使用对象而非数组——调用者无需依赖顺序。
- 严禁扩展内置原型(、
Array.prototype)。使用工具函数或子类。Object.prototype
副作用循环优先使用,数据转换优先使用方法(、、、、、),需要索引的循环使用。完整的迭代决策表请参见。
for...ofArray.prototype.map.filter.reduce.find.some.everyforreferences/objects-and-arrays.md当键不是字符串或由用户提供时使用(避免原型污染)。去重使用()。惰性序列和延迟计算使用生成器()。
MapSet[...new Set(items)]function*Classes
类
- ES syntax is REQUIRED. Do not use function constructors or prototype manipulation.
class - fields for encapsulation. Not
#privateconvention._ - Composition over inheritance. Use only for true "is-a" relationships.
extends - No empty constructors. If the constructor only calls , omit it.
super() - Static methods for operations that don't need instance state.
- Methods can return for fluent/chainable APIs.
this - Don't force classes when plain functions and objects suffice. A class with one method is a function in disguise.
- 必须使用ES 语法。不要使用函数构造函数或原型操作。
class - 封装使用字段。不要使用
#private约定。_ - 组合优于继承。仅当存在真正的"is-a"关系时使用。
extends - 不要使用空构造函数。如果构造函数仅调用,则省略它。
super() - 无需实例状态的操作使用静态方法。
- 方法可返回以实现流畅/链式API。
this - 当普通函数和对象足够时,不要强行使用类。只有一个方法的类本质上是伪装的函数。
JSDoc Typing
JSDoc类型
For pure JavaScript projects that don't use TypeScript, use JSDoc annotations to provide type safety through editor
tooling. Enable at file top or in .
// @ts-checkcheckJsjsconfig.jsonCore tags: , , , (with ), . See
for the full tag catalog including , , class modifiers, and
type import syntax.
@type@param@returns@typedef@property@templatereferences/jsdoc.md@callback@enum对于不使用TypeScript的纯JavaScript项目,使用JSDoc注释通过编辑器工具提供类型安全。在文件顶部启用或在中设置。
// @ts-checkjsconfig.jsoncheckJs核心标签:、、、(配合)、。完整的标签目录包括、、类修饰符和类型导入语法,请参见。
@type@param@returns@typedef@property@template@callback@enumreferences/jsdoc.mdJSDoc Best Practices
JSDoc最佳实践
- Annotate public API boundaries — exported functions, classes, module-level variables. Internal code often needs fewer annotations; types flow from context.
- Prefer inline TypeScript syntax in JSDoc types: over
{string | number}.{(string|number)} - Use for shared shapes — define once near file top or in
@typedef.types.js - Don't annotate the obvious — if is clearly a number, skip
const x = 5.@type
- 标注公共API边界——导出的函数、类、模块级变量。内部代码通常需要更少的注释;类型会从上下文自动推导。
- JSDoc类型中优先使用内联TypeScript语法:优于
{string | number}。{(string|number)} - 共享结构使用——在文件顶部或
@typedef中定义一次。types.js - 不要标注显而易见的类型——如果明显是数字,跳过
const x = 5。@type
Application
规范应用
When writing JavaScript code:
- You MUST apply all conventions silently — don't narrate each rule being followed.
- If an existing codebase contradicts a convention, you MUST follow the codebase and flag the divergence once.
When reviewing JavaScript code:
- You MUST cite the specific violation and show the fix inline.
- You MUST NOT lecture or quote the rule — state what's wrong and how to fix it.
Bad review comment:
"According to best practices, use const instead of let
when the variable is never reassigned."
Good review comment:
"`let` -> `const` — `config` is never reassigned."编写JavaScript代码时:
- 必须静默应用所有规范——无需逐一说明遵循的规则。
- 如果现有代码库与规范冲突,必须遵循代码库的写法,并一次性标注差异点。
评审JavaScript代码时:
- 必须明确指出具体违规点,并在代码中展示修复方案。
- 不要说教或引用规则原文——直接说明问题所在及修复方式。
不好的评审评论:
"根据最佳实践,当变量无需重新赋值时应使用const而非let。"
好的评审评论:
"`let` -> `const` — `config`从未被重新赋值。"Code Navigation — LSP Required
代码导航——必须使用LSP
A LSP server is configured for all JS/TS file types (, , , , ,
, , ). You MUST use LSP tools for code navigation instead of Grep or Glob. LSP understands module
resolution, type inference, scope rules, and project boundaries — text search does not.
typescript-language-server.js.jsx.ts.tsx.mjs.cjs.mts.cts所有JS/TS文件类型(、、、、、、、)均配置了 LSP服务器。必须使用LSP工具进行代码导航,而非Grep或Glob。LSP理解模块解析、类型推断、作用域规则和项目边界——文本搜索无法做到这些。
.js.jsx.ts.tsx.mjs.cjs.mts.ctstypescript-language-serverTool Routing
工具使用指南
- Find where a function/class/variable is defined → — Resolves imports, re-exports, aliases
goToDefinition - Find all usages of a symbol → — Scope-aware, no false positives from string matches
findReferences - Get type signature, docs, or return types → — Instant type info without reading source files
hover - List all exports/symbols in a file → — Structured output vs grepping for
documentSymbol/function/classexport - Find a symbol by name across the project → — Searches all modules
workspaceSymbol - Find implementations of an interface → — Knows the type system
goToImplementation - Find what calls a function → — Precise call graph across module boundaries
incomingCalls - Find what a function calls → — Structured dependency map
outgoingCalls
Grep/Glob remain appropriate for: text in comments, string literals, log messages, TODO markers, config values, env
vars, CSS classes, file name patterns, URLs, error message text.
When spawning subagents for JS/TS codebase exploration, you MUST instruct them to use LSP tools. Subagents have access to the
same LSP server.
- 查找函数/类/变量的定义位置 → — 解析导入、重导出、别名
goToDefinition - 查找符号的所有引用 → — 作用域感知,无字符串匹配导致的误报
findReferences - 获取类型签名、文档或返回类型 → — 无需阅读源文件即可获取即时类型信息
hover - 列出文件中的所有导出/符号 → — 结构化输出,优于搜索
documentSymbol/function/classexport - 在项目中按名称查找符号 → — 搜索所有模块
workspaceSymbol - 查找接口的实现 → — 了解类型系统
goToImplementation - 查找调用某个函数的位置 → — 跨模块边界的精确调用图
incomingCalls - 查找某个函数调用的内容 → — 结构化依赖图
outgoingCalls
Grep/Glob仍适用于:注释中的文本、字符串字面量、日志消息、TODO标记、配置值、环境变量、CSS类、文件名模式、URL、错误消息文本。
当生成子代理探索JS/TS代码库时,必须指示它们使用LSP工具。子代理可访问同一LSP服务器。
Integration
技能集成
The coding skill governs workflow; this skill governs JavaScript implementation choices. For TypeScript projects,
the typescript skill extends this one.
coding技能管控工作流;本技能管控JavaScript实现选择。对于TypeScript项目,typescript技能是本技能的扩展。",