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