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

时间:2021-01-12 16:35:17

I've been messing around with the ECMA-262 standard (ECMAScript Language Specification, 3rd edition, if it matters for this - I have not found any difference between the 3rd and 5th edition on String Type / String Object).

我一直在纠结于ECMA-262标准(ECMAScript语言规范,第三版,如果重要的话——我在字符串类型/字符串对象的第三版和第五版之间没有发现任何区别)。

There's one thing that baffles me: the difference between the String Type and the String Object. Yes I know the difference in the sense that the String Type is a sequence of 16-bit UTF-16 units and the String Object is a built-in object with its internal Class property set to "String" and its internal Value property set to a value of the String Type.

有一件事让我困惑:字符串类型和字符串对象之间的区别。是的,我知道字符串类型是16位UTF-16单元的序列,字符串对象是一个内置对象,其内部类属性设置为“String”,其内部值属性设置为字符串类型的值。

But reading the specification, the string type does not seem to expose any methods; that is, it's just a value without any additional properties. Take this code, everything is exactly as expected:

但是在阅读规范时,字符串类型似乎不公开任何方法;也就是说,它只是一个没有附加属性的值。拿这段代码来说,一切都完全符合预期:

document.writeln(typeof "foo"); // 'string'
document.writeln(typeof new String("foo")); // 'object'

The first type is the actual String Type and the second is the Object Type (it's an object of class String, but its data type is object). However, looking at this:

第一个类型是实际的字符串类型,第二个类型是对象类型(它是类字符串的对象,但是它的数据类型是Object)。然而,看这个:

"foo".charAt(0);

fooStrObj = new String("Foo");
fooStrObj.charAt(0);

They both seem to expose the same functions, but there are no functions on the String Type defined in the ECMA-262 standard; all the functions it exposes are from the String.prototype object (and I can see no reference to the fact that the String Type magically exposes all the properties and functions of the String.prototype object in the ECMA-262 standard). So are the values of type String Type automatically promoted to a String Object with the original String Type value as its internal Value property?

它们似乎都公开了相同的函数,但是在ECMA-262标准中定义的字符串类型上没有函数;它公开的所有函数都来自字符串。prototype对象(我不认为字符串类型会神奇地暴露字符串的所有属性和函数)。原型对象在ECMA-262标准中)。那么,类型字符串类型的值是否自动被提升为具有原始字符串类型值作为其内部值属性的字符串对象?

And if they are treated exactly the same (which for all intents and purposes they seem to be), why have two different ways to represent a String?

如果它们被处理的完全一样(实际上它们看起来是一样的),为什么有两种不同的方式来表示字符串呢?

2 个解决方案

#1


41  

Strings are a value type in JS, so they can't have any properties attached to them, no prototype, etc. Any attempt to access a property on them is technically performing the JS [[ToObject]] conversion (in essence new String).

字符串是JS中的一种值类型,因此它们不能有任何属性附加在它们上,没有原型等等。任何访问它们上属性的尝试都是在技术上执行JS [[ToObject]]]转换(本质上是新字符串)。

Easy way of distinguishing the difference is (in a browser)

区分不同的简单方法是(在浏览器中)

a = "foo"
a.b = "bar"
alert("a.b = " + a.b); //Undefined

A = new String("foo");
A.b = "bar";
alert("A.b = " + A.b); // bar

Additionally while

此外,

"foo" == new String("foo")

is true, it is only true due to the implicit type conversions of the == operator

是真的吗?它只是因为==运算符的隐式类型转换而成立吗

"foo" === new String("foo")

will fail.

将会失败。

#2


12  

It's analogous to the difference between int and Integer in Java.

它类似于Java中int和Integer的区别。

According to the standard, strings are automatically converted to String objects when you try to call a method. See ECMA 262-3 section 11.2.1; step 5 calls ToObject (which is defined in section 9.9).

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

11.2.1 Property Accessors
[...]
The production MemberExpression : MemberExpression [ Expression ] is evaluated as follows:

11.2.1属性访问器[…]生产MemberExpression: MemberExpression [Expression]的评价如下:

  1. Evaluate MemberExpression.
  2. 评估MemberExpression。
  3. Call GetValue(Result(1)).
  4. (1)调用GetValue(结果)。
  5. Evaluate Expression.
  6. 评估表达式。
  7. Call GetValue(Result(3)).
  8. (3)调用GetValue(结果)。
  9. Call ToObject(Result(2)).
  10. 调用ToObject(结果(2))。
  11. Call ToString(Result(4)).
  12. (4)调用ToString(结果)。
  13. Return a value of type Reference whose base object is Result(5) and whose property name is Result(6).
  14. 返回类型引用的值,其基对象为Result(5),其属性名为Result(6)。


9.9 ToObject

9.9 ToObject

The operator ToObject converts its argument to a value of type Object according to the following table:
[...]
Create a new String object whose [[value]] property is set to the value of the string. See 15.5 for a description of String objects.

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

As a specification technique, this is a hack to explain how strings can appear to have methods even though they're not really objects.

作为一种规范技术,这是一种解释字符串如何看起来有方法的hack,尽管它们并不是真正的对象。

Apart from that, the wrapper objects are not very useful. I don't know why they're in the language. I rather wish they weren't. :)

除此之外,包装器对象并不是很有用。我不知道他们为什么用这种语言。我倒希望他们不是。:)

#1


41  

Strings are a value type in JS, so they can't have any properties attached to them, no prototype, etc. Any attempt to access a property on them is technically performing the JS [[ToObject]] conversion (in essence new String).

字符串是JS中的一种值类型,因此它们不能有任何属性附加在它们上,没有原型等等。任何访问它们上属性的尝试都是在技术上执行JS [[ToObject]]]转换(本质上是新字符串)。

Easy way of distinguishing the difference is (in a browser)

区分不同的简单方法是(在浏览器中)

a = "foo"
a.b = "bar"
alert("a.b = " + a.b); //Undefined

A = new String("foo");
A.b = "bar";
alert("A.b = " + A.b); // bar

Additionally while

此外,

"foo" == new String("foo")

is true, it is only true due to the implicit type conversions of the == operator

是真的吗?它只是因为==运算符的隐式类型转换而成立吗

"foo" === new String("foo")

will fail.

将会失败。

#2


12  

It's analogous to the difference between int and Integer in Java.

它类似于Java中int和Integer的区别。

According to the standard, strings are automatically converted to String objects when you try to call a method. See ECMA 262-3 section 11.2.1; step 5 calls ToObject (which is defined in section 9.9).

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

11.2.1 Property Accessors
[...]
The production MemberExpression : MemberExpression [ Expression ] is evaluated as follows:

11.2.1属性访问器[…]生产MemberExpression: MemberExpression [Expression]的评价如下:

  1. Evaluate MemberExpression.
  2. 评估MemberExpression。
  3. Call GetValue(Result(1)).
  4. (1)调用GetValue(结果)。
  5. Evaluate Expression.
  6. 评估表达式。
  7. Call GetValue(Result(3)).
  8. (3)调用GetValue(结果)。
  9. Call ToObject(Result(2)).
  10. 调用ToObject(结果(2))。
  11. Call ToString(Result(4)).
  12. (4)调用ToString(结果)。
  13. Return a value of type Reference whose base object is Result(5) and whose property name is Result(6).
  14. 返回类型引用的值,其基对象为Result(5),其属性名为Result(6)。


9.9 ToObject

9.9 ToObject

The operator ToObject converts its argument to a value of type Object according to the following table:
[...]
Create a new String object whose [[value]] property is set to the value of the string. See 15.5 for a description of String objects.

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

As a specification technique, this is a hack to explain how strings can appear to have methods even though they're not really objects.

作为一种规范技术,这是一种解释字符串如何看起来有方法的hack,尽管它们并不是真正的对象。

Apart from that, the wrapper objects are not very useful. I don't know why they're in the language. I rather wish they weren't. :)

除此之外,包装器对象并不是很有用。我不知道他们为什么用这种语言。我倒希望他们不是。:)