javascript字符串类型和字符串对象之间的区别?

thr*_*thr 64 javascript

我一直在搞乱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)

将失败.

  • 见http://bclary.com/2004/11/07/#a-11.9.3.如果你在心理上单步执行它,你将在步骤20结束调用String对象上的ToPrimitive; 最终调用它的`.toString()`方法. (5认同)

Jas*_*rff 12

它类似于Java intIntegerJava 之间的区别.

根据标准,String当您尝试调用方法时,字符串会自动转换为对象.见ECMA 262-3第11.2.1节 ; 第5步调用ToObject(在第9.9节中定义).

11.2.1属性访问器
[...]
生成MemberExpression:MemberExpression [Expression]的计算方法如下:

  1. 评估MemberExpression.
  2. 调用GetValue(Result(1)).
  3. 评估表达.
  4. 调用GetValue(Result(3)).
  5. 调用ToObject(结果(2)).
  6. 调用ToString(Result(4)).
  7. 返回Reference类型的值,其基础对象为Result(5),其属性名称为Result(6).


9.9 ToObject

运算符ToObject根据下表将其参数转换为Object类型的值:
[...]
创建一个新的String对象,其[[value]]属性设置为字符串的值.有关String对象的说明,请参见15.5.

作为一种规范技术,这是一个解释字符串如何看起来具有方法的黑客,即使它们不是真正的对象.

除此之外,包装器对象不是很有用.我不知道为什么他们会说这种语言.我宁愿他们不是.:)

  • 在少数情况下可以优化区别,但大多数String对象对性能不利,您应该避免它们. (2认同)