如何在ES6变量声明后判断其为var/const/let类型?
Great question! I totally get why you'd want this for debugging, compiler development, or academic research—even though we usually rely on declaration context to know the difference, having a runtime check would be super handy. Let's break down what's possible and what's not:
First: There's no built-in "typeof for declaration type"
Unlike typeof or checking an object's constructor, JavaScript doesn't expose a native API that directly tells you whether a variable was declared with var, let, or const. Once the variable is created, the engine doesn't keep that exact "declaration keyword" metadata accessible to runtime code.
But we can work around this by checking the unique behaviors of each declaration type:
1. Distinguish var from let/const (global scope only)
In the global scope, var declarations get attached to the global object (like window in browsers), while let and const declarations don't. You can use this quirk to check global variables:
function isGlobalVar(variableName) { // Check if the variable exists on the global object and is its own property return typeof window[variableName] !== 'undefined' && Object.prototype.hasOwnProperty.call(window, variableName); } // Example usage: var globalVar = "I'm var"; let globalLet = "I'm let"; console.log(isGlobalVar('globalVar')); // true console.log(isGlobalVar('globalLet')); // false
Heads up: This only works for global variables. Inside functions or blocks, var doesn't attach to any accessible object, so this trick won't work.
2. Check if a variable is const (via re-assignment attempt)
const variables can't be re-assigned (though their underlying values can still mutate if they're objects/arrays). You can test this by trying to re-assign and catching the resulting TypeError:
function isConst(variableName, context = window) { try { // Attempt to re-assign the variable context[variableName] = 'test-assignment'; return false; } catch (e) { // Verify the error is specifically about constant assignment return e instanceof TypeError && e.message.includes('assignment to constant variable'); } } // Example usage: const fixedVar = 42; let mutableVar = 100; console.log(isConst('fixedVar')); // true console.log(isConst('mutableVar')); // false
Caveats here:
- This only works for variables accessible in the provided
context(global variables are easiest; function-scoped variables need their function's context, which isn't always accessible). - If a
letvariable is frozen (e.g., withObject.freeze()) or in a strict mode context where re-assignment is restricted for other reasons, this might give a false positive.
3. For compiler/academic use: Analyze the AST instead
If you're building a JS compiler or doing deep research, runtime checks aren't the way to go. Instead, parse the code into an Abstract Syntax Tree (AST) before execution. Tools like Espree or Acorn can parse code and let you inspect exactly how each variable was declared (look for VariableDeclaration nodes with a kind property set to "var", "let", or "const").
This is the reliable way to get the declaration type, since it looks at the source code directly rather than the runtime state where metadata is lost.
Wrap-up
While there's no universal, built-in method like getDeclarationType(variable) that works everywhere, you can use context-specific hacks for runtime checks. For serious compiler work or academic research, analyzing the AST is the robust solution.
内容的提问来源于stack exchange,提问作者mikemaccana

