在表面上,const
允许您澄清JavaScript程序中的某些变量不会更改:
const x = 3;
x++; // TypeError 💥
但是,一旦您使用非启示价值,这就会分解:
const x = [1, 2];
x.push(3); // Sure, why not?
有两种思考JavaScript允许的思考方法:
-
const
大约哪个对象绑定到x
。当您将3
推入数组时,x
仍指向同一对象。阵列更改了,但是x
没有。 - javaScript别无选择,只能允许,因为当前的
const
已经是它可以提供的最佳一致行为。
看(2),请考虑:
const x = getAThing();
const valueBefore = x.value;
someOtherFunction();
const valueAfter = x.value;
valueBefore === valueAfter; // true?
(Complete example with koude7 result。)
在JavaScript中,很难确定x.value
是否由someOtherFunction()
更改,因此它不知道(DeepSyle)const
是否已违反。
(实际上,对于这样的简单演示可能是可以的,但是对于迅速在真实程序中迅速出现的更为复杂的示例并不是正确的。)
另外,您也可以在运行时跟踪内存本身的const
状态,但这每次使用const
时都会添加运行时开销。大型物体也可以由许多具有不同const
要求的较小物体组成,可能会引起很多自己的混乱。
如果您想像您的意思那样说const
,那么您可能需要避免编写像getAThing()
和someOtherFunction()
这样更改共享对象的功能。但是,随着计划的扩展,很难防止这种情况。此外,采用这种方法的精神成本。
输入valuescript。这是带有价值语义的打字稿(和JavaScript)的方言。一切都是a value ,就像第一个示例中的3
一样。 3
是3
是3
。您可以增加变量以使其成为4
,但这会更改变量。将实际数字3
变成4
是胡说八道。
在valuescript中,对象也是如此。 [1, 2]
是[1, 2]
是[1, 2]
。您可以将3
推入其中以获取[1, 2, 3]
,但这会更改 variable 。将实际的[1, 2]
变成[1, 2, 3]
是胡说八道。
这就是为什么ValueScript给您第二个示例的类型错误:
const x = [1, 2];
x.push(3); // TypeError 💥
知道一个方法是否更改类实例仍然有些棘手,但是在值cript中它是可管理的,因为更改始终是局部的。 valuescript使用const_subcall
指令对.push
,可确保在呼叫内更改this
。
valuescript能够使用参考计数和抄写纸上而不是共享引用来保持本地事物。否则,您也可以这样违反const
:
export default function main() {
const leftBowl = ["apple", "mango"];
let rightBowl = leftBowl;
rightBowl.push("peach");
return leftBowl.includes("peach");
// JavaScript: true (even though leftBowl is const)
// ValueScript: false
}
在JavaScript中,leftBowl
和rightBowl
是相同的对象,因此将桃子放入rightBowl
也将桃子放入leftBowl
,即使leftBowl
是const
。
valuescript不会以这种方式将它们链接在一起。 rightBowl
可以自由修改,但这对leftBowl
没有影响。这很好,因为leftBowl
是const
。
使用const
控制变量的能力也具有除编程清晰度之外的好处。编译器能够知道变量何时发生变化以及何时不发生变化是非常有益的。特别是,即使尚未使用const
关键字,变量也有效地有效地 :
- 被捕获到函数的变量
- 导入变量
在这些情况下,编译器还使用const_subcall
进行方法调用以确保它们保持恒定。
const
要求的这些扩展以及知道变量何时常数的增强能力也将对valuescript中静态分析的未来非常有益。这意味着分析仪会更频繁地知道您的程序的运作方式,这将有助于其优化,找到问题并减少二元尺寸。
valuescript处于早期开发中,但它具有广泛的playground,显示了很大一部分JavaScript。也是open source。