Javascript 中的简单类型是不可变的,并且不像对象那样是键控集合。为什么下面的代码只是返回赋值的值而没有提示?
var foo = 'bar';
foo.newProperty = 'blaha';
第二个语句只返回'blaha'。但是,如果您现在调用 foo.newProperty
,您自然会得到 undefined
,因为简单类型不是散列。所以问题是,尝试属性分配时不应该抛出异常,就像在 Python 中尝试替换元组中的值时出现 TypeError 一样。或者是否有一些模糊的语法特征使 foo.newProperty
的计算结果出乎意料?
最佳答案
foo.newProperty
的语法有一个模糊的特性。 :-) 字符串和数字可以是基元或对象,解释器会在需要时自动从基元转换为对象(反之亦然)。
var foo = 'bar'; // `foo` is a primitive
alert(typeof foo); // alerts "string"
var foo2 = new String('bar'); // `foo2` is an object
alert(typeof foo2); // alerts "object"
向基元添加属性有效但后来似乎无效的原因是转换仅用于表达式的目的。所以如果我这样做:
foo.newProperty = 'blaha';
从 foo
变量中检索原始字符串值,然后将其从原始字符串转换为表达式的对象,但仅用于表达式(我们还没有为变量 foo
分配了一个新值,毕竟,只是更改了从 foo
中检索到的表达式的值以使表达式有效)。如果我们想确保 foo
引用一个 String
object,我们必须故意这样做:
foo = new String(foo);
foo.newProperty = 'blaha';
the spec 的第 9 节(“类型转换和测试”)和第 11.2.1 节(“属性访问器”)(稍微)介绍了这种自动转换。 ,尽管是通常笨拙的规范说话风格。 :-)
关于你的问题“......这种自动包装有充分的理由吗?”下面:哦,是的。这种从基元到对象的自动提升非常重要。例如:
var foo = "bar";
alert(foo.length);
基元没有属性,所以如果没有任何自动提升,上面的第二行就会失败。 (自然地,实现可以自由优化,这样就不需要实际对象创建,只要它的行为符合规范的外部指示。)类似地:
var foo = "bar";
alert(foo.indexOf('a')); // alerts 1
基元不是对象,因此它们没有原型(prototype)链,那么 indexOf
属性从何而来?当然,答案是原语被提升为 String
实例,并且 String.prototype
具有 indexOf
。
更引人注目的是:
alert((4).toFixed(2)); // alerts "4.00"
由于数字也会根据需要进行提升,因此这样做是完全可以接受的。您必须使用括号 - 例如 (4)
而不仅仅是 4
- 来满足语法(因为 .
在文字中number 是小数点而不是属性访问器),尽管如果你想变得真正深奥,你可以使用 4['toFixed'](2)
。我不会。 :-)
关于javascript - 为什么尝试在 Javascript 中为简单类型的属性赋值不会引发异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4407382/