我一直在搞乱ECMA-262标准( ECMAScript语言规范,第3版,如果它对此很重要 - 我没有发现第3版和第5版之间的任何区别类型/字符串对象)。
有一件事令我感到困惑:String Type和String Object之间的区别。是的我知道 String Type 是一系列16位UTF-16单位而 String Object 是内置对象及其内部的区别 Class 属性设置为“String”,其内部 Value 属性设置为 String Type 的值。
但是阅读规范,字符串类型似乎没有公开任何方法;也就是说,它只是一个没有任何附加属性的值。拿这个代码,一切都完全符合预期:
document.writeln(typeof "foo"); // 'string'
document.writeln(typeof new String("foo")); // 'object'
第一种类型是实际的字符串类型,第二种是对象类型(它是类 String 的对象,但是它的数据type是object)。但是,看看这个:
"foo".charAt(0);
fooStrObj = new String("Foo");
fooStrObj.charAt(0);
它们似乎都暴露了相同的功能,但ECMA-262标准中定义的 String Type 没有任何功能;它暴露的所有函数都来自String.prototype对象(我看不到 String Type 在ECMA中神奇地暴露String.prototype对象的所有属性和函数这一事实的引用 - 262标准)。类型 String Type 的值也会自动提升为 String Object ,其原始 String Type 值为其内部值 property?
如果它们被完全相同(对于所有意图和目的而言),为什么有两种不同的方式来表示 String ?
答案 0 :(得分:44)
字符串是JS中的值类型,因此它们不能附加任何属性,没有原型等。任何尝试访问它们的属性在技术上都在执行JS [[ToObject]]转换(实质上)新字符串)。
区分差异的简便方法是(在浏览器中)
a = "foo"
a.b = "bar"
alert("a.b = " + a.b); //Undefined
A = new String("foo");
A.b = "bar";
alert("A.b = " + A.b); // bar
此外,
"foo" == new String("foo")
是真的,由于==运算符
的隐式类型转换,它才是真的"foo" === new String("foo")
会失败。
答案 1 :(得分:12)
它类似于Java中int
和Integer
之间的差异。
根据标准,当您尝试调用方法时,字符串会自动转换为String
个对象。见ECMA 262-3 section 11.2.1;第5步调用ToObject
(在第9.9节中定义)。
11.2.1属性访问者
[...]
生成MemberExpression:MemberExpression [Expression]的计算方法如下:
- 评估MemberExpression。
- 调用GetValue(Result(1))。
- 评估表达。
- 调用GetValue(Result(3))。
- 调用ToObject(结果(2))。
- 调用ToString(结果(4))。
- 返回类型为Reference的值,其基础对象为Result(5),其属性名称为Result(6)。
醇>
9.9 ToObject
运算符ToObject根据下表将其参数转换为Object类型的值:
[...]
创建一个新的String对象,其[[value]]属性设置为的值 串。有关String对象的说明,请参见15.5。
作为一种规范技术,这是一个解释字符串如何看起来具有方法的黑客,即使它们不是真正的对象。
除此之外,包装器对象不是很有用。我不知道为什么他们会说这种语言。我宁愿他们不是。 :)