JavaScript中给字符串length等只读属性赋值的行为及返回值疑问
关于JavaScript字符串length属性赋值的相关问题解答
我们先把示例代码的完整运行效果补全,就能更清楚看到赋值操作的实际影响:
var str = "test"; console.log(str.length); // 输出:4 console.log(str.length = 3); // 输出:3 // 额外验证赋值是否生效 console.log(str.length); // 输出仍然是4,原字符串没有任何变化
为什么给字符串length属性赋值没有生效?
JS里的字符串属于原始值类型,本身是没有属性和方法的。我们每次访问str.length的时候,JS底层会临时创建一个对应的String包装对象,读取完length属性后这个临时对象就会被立刻销毁。
而String实例的length属性本身就是不可写的只读属性,你给str.length = 3的赋值操作,实际是作用在这个临时创建的包装对象上,非严格模式下会直接静默失败,严格模式会抛出类型错误。临时对象用完就销毁了,原原始字符串完全不受影响,所以后续再访问length还是4。
为什么赋值操作会返回3而不是修改后的左值?
这是ECMAScript规范对赋值运算符的固定定义:赋值表达式的返回值始终是右操作数的求值结果,和赋值是否成功没有关系。不管你给左值赋值的操作有没有生效,a = xxx这个表达式的结果永远是xxx的值,所以这里自然返回3。
为什么规范要设计成返回右操作数而不是左操作数?
核心是为了支持连续赋值的语法:
let a, b, c; a = b = c = 10; // 等价于 c = 10; b = 10; a = 10; 三个变量都正确赋值为10
如果赋值表达式返回左操作数的话,一旦左值是只读属性、或者有自定义getter导致返回值和赋值不一致时,连续赋值的结果就会完全不符合预期,所以从语言设计的合理性出发,选择了返回右操作数的规则。
内容的提问来源于stack exchange,提问作者MTB
相关产品推荐
相关产品推荐

