有谁知道一些技巧怎么做?我尝试使用try-catch
:
"use strict";
const a = 20;
var isConst = false;
try {
var temp = a; a = a+1; a = temp;
} catch (e) {
isConst = true;
}
但不幸的是,它仅适用于" strict"模式。没有"使用严格"它以静默方式执行所有语句,而不修改a
。此外,我无法将此代码包装到一些方便的函数中(例如isConstant(someConst)
),因为我传递给该函数的任何参数都将是一个新变量。所以任何人都知道如何创建isConstant()
函数?
答案 0 :(得分:2)
我认为没有,但我也不认为这是一个大问题。我认为有能力知道变量是否为const
并且存在于其他一些语言中可能是有用的,但实际上,因为您(或团队中的某个人)将定义这些变量,您和# 39; d知道变量的范围和类型。换句话说,不,你不能,但它也不是问题。
唯一可能有用的情况是,如果您可以在运行时更改mutable
属性,并且更改此属性具有实际的性能优势; let
,const
和var
与编译器大致相同,唯一的区别是编译器会跟踪const
并在编译之前检查分配。
另外需要注意的是,就像let
一样,const
的范围限定为当前范围,所以如果您有类似的内容:
'use strict';
const a = 12;
// another scope
{
const a = 13;
}
它有效。请注意,如果您未在新范围内明确说明const a = 13
,它会在更高的范围内查找,并且会出现Read Only
或Assignment
错误:
'use strict';
const a = 12;
{
a = 13; // will result in error
}
答案 1 :(得分:1)
基于此处的一些答案,我编写了此代码段(用于客户端JS),该代码段将告诉您最后一次声明“变量”的方式-我希望它很有用。
使用以下命令找出x
的最后声明(取消注释x
的声明以对其进行测试):
// x = 0
// var x = 0
// let x = 0
// const x = 0
const varName = "x"
console.log(`Declaration of ${varName} was...`)
try {
eval(`${varName}`)
try {
eval(`var ${varName}`);
console.log("... last made with var")
} catch (error) {
try {
eval(`${varName} = 0`)
console.log("... last made with let")
} catch (error) {
console.log("... last made with const")
}
}
} catch (error) {
console.log("... not found. Undeclared.")
}
有趣的是,在没有var
,let
或const
即x = 0
的情况下进行声明会导致var
默认使用。同样,使用var
在函数范围中重新声明函数参数。
答案 2 :(得分:0)
只需检查您的重新分配是否真的有所作为:
var isConst = function(name, context) {
// does this thing even exist in context?
context = context || this;
if(typeof context[name] === "undefined") return false;
// if it does exist, a reassignment should fail, either
// because of a throw, or because reassignment does nothing.
try {
var _a = context[name];
context[name] = !context[name];
if (context[name] === _a) return true;
// make sure to restore after testing!
context[name] = _a;
} catch(e) { return true; }
return false;
}.bind(this);
你需要try / catch因为重新分配可以抛出异常(比如在Firefox中),但是当它没有(比如在Chrome中)时,你只需检查你的“这总是会改变价值“重新分配实际做了任何事情。
一个简单的测试:
const a = 4;
var b = "lol";
isConst('a'); // -> true
isConst('b'); // -> false
如果您在不同的上下文中声明了consts,则传递该上下文以强制解析正确的对象。
缺点:这不适用于在对象范围之外声明的变量。好处:在其他地方宣布它们是完全没有意义的。例如,在函数范围内声明它们会导致const
关键字无用:
function add(a) {
return ++a;
}
function test() {
const a = 4;
console.log(add(a));
}
test(); // -> 5
即使a
在test()中是常量,如果你将它传递给其他任何东西,它也会作为常规的可变值传递,因为它现在只是arguments
列表中的“一件事”。 / p>
此外,拥有const
的唯一原因是因为它没有改变。因此,不断重新创建它,因为你正在调用一个不止一次使用它的函数,这意味着你的const
应该在函数之外生存,所以再一次,我们被迫将变量放在一个对象中范围。
答案 3 :(得分:-1)
该问题涉及早期ES6实施中的不合规行为,尤其是V8(Node.js 4和传统Chrome版本)。现代ES6实现中不存在这个问题,无论是在严格模式还是在草率模式下。 const
重新分配应始终生成TypeError
,可以使用try..catch
进行重新分配。
无法isConstant
函数,因为const
变量的值无法识别。
最好在严格模式下运行脚本,从而避免特定于草率模式的问题。
即使在草率模式中定义了变量,也可以在嵌套函数范围中启用严格模式:
const foo = 1;
// ...
let isConst = false;
(() => {
'use strict';
try {
const oldValue = foo;
foo = 'new value';
foo = oldValue;
} catch (err) {
isConst = true;
}
})();
使用JavaScript和其他语言中使用的UPPERCASE_CONSTANT
约定是有益的。它允许在没有IDE帮助的情况下明确地将变量识别为常量,并避免大多数意外重新分配的问题。