const和readonly在引用类型上的一个小坑
2019-05-30 本文已影响0人
JsForLife
const和redaonly这两个大家应该都熟悉,当它们修饰的是非应用类型的数据时,表现很正常。
const a = 1;
interface ReadOnlyObject {
readonly a:number;
}
const obj:ReadOnlyObject = {
a:1,
};
a = 2;
obj.a = 2;
很显然,上面最后两句赋值语句都会报错。可如果我们把它们修饰的对象换成引用类型:
const a:number[] = [1];
interface ReadOnlyObject {
readonly a:number[];
}
const obj:ReadOnlyObject = {
a: [1],
};
a.push(2);
obj.a.push(2);
这次我们往const和readonly修饰的两个数组push新值,结果执行成功。
因为这两个修饰符号在修饰引用类型的数据时,只是限制不能修改引用,没有限制修改引用所指向的数据。即你一开始指向了数组a就不能它改成指向另一个数组b,而数组a里面的数据可以随便你改。这就导致了,有些同学想用单独用这两个修饰符号定义一个不可被修改的数组或对象常量,缺因为绕过ts检查而误修改。
解决办法
解决办法其实也很简单,数组里的项加上readonly修饰符号就可以了。
const a:readonly number[] = [1];
interface ReadOnlyObject {
// 这里,对象内这个数组的interface不这么写的话会报错,当然如果你要其他可行的写法,欢迎在评论区留言给我
readonly a:readonly [number];
}
const obj:ReadOnlyObject = {
a:[1],
};
a.push(2); // 报错
obj.a.push(2); // 报错
这样数组就不允许加减项了。