JavaScript中object是否可变?为什么String实例对象是不可变的?
为什么通过new String创建的字符串实例对象无法被修改
首先要先澄清一个认知误区:你提到的「JavaScript中只有对象和数组是可变的」这个说法不严谨,完整表述应该是普通自定义对象、数组默认是可变的,而原始值以及原始值对应的包装类实例都是不可变的。
你遇到的现象核心有两个原因:
- String包装类的实例本身就是JS规范定义的不可变对象,它内部存储实际字符串值的
[[PrimitiveValue]]内部属性是只读的,JS引擎不允许修改这个属性的取值 - 所有挂载在
String.prototype上的方法(包括你用到的toUpperCase),默认都不会修改原实例本身,只会把处理后的结果作为新值返回
你贴的代码没有接收方法的返回值,自然看不到变化,你可以修改代码验证逻辑:
var a = new String("abc") // 接收toUpperCase的返回值 var upperRes = a.toUpperCase() console.log(a) // 输出 String {'abc'},原实例不变 console.log(upperRes) // 输出 ABC,是处理后的新原始字符串值
就算你尝试手动修改String实例的内容也会失效,因为它的类数组索引属性也是只读的:
var a = new String("abc") a[0] = 'x' console.log(a) // 仍然输出 String {'abc'}
本质上所有原始类型对应的包装类(String、Number、Boolean、Symbol、BigInt)的实例,都是特殊的不可变对象,设计上就不允许修改自身存储的原始值,所以才会出现你看到的「明明是对象却没法修改」的现象。
内容的提问来源于stack exchange,提问作者Abhishek Bhattarai
相关产品推荐
相关产品推荐

