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

IT技术 javascript
2021-02-12 15:32:31

我一直在搞弄 ECMA-262 标准(ECMAScript 语言规范,第 3 版,如果这很重要的话 - 我没有发现第 3 版和第 5 版在字符串类型/字符串对象上有任何区别)。

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

但是看了规范,string类型好像没有暴露任何方法;也就是说,它只是一个没有任何附加属性的值。拿这段代码,一切都和预期的一样:

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

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

"foo".charAt(0);

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

它们似乎都公开了相同的函数,但是在 ECMA-262 标准中定义String Type上没有函数它公开的所有函数都来自 String.prototype 对象(并且我看不到字符串类型神奇地公开了 ECMA-262 标准中 String.prototype 对象的所有属性和函数的事实)。那么String Type 类型的值是否会自动提升为一个String Object,并将原始String Type值作为其内部Value属性?

如果它们的处理方式完全相同(就所有意图和目的而言,它们似乎都是如此),为什么要用两种不同的方式来表示String

2个回答

字符串是 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")

将失败。

谢谢,这就是我有点怀疑的地方,你能指出我在实际规范中的哪个地方是这样说的吗?
2021-03-14 15:32:31
bclary.com/2004/11/07/#a-11.9.3如果您在精神上逐步完成它,您将在第 20 步结束对 String 对象调用 ToPrimitive;最终调用它的.toString()方法。
2021-03-20 15:32:31
字符串原语和字符串对象的区别:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-26 15:32:31
非常感谢伙计!学到了新东西,你帮了我很多。:) +1
2021-04-04 15:32:31
一个非常重要的区别new String("")是真实性。
2021-04-09 15:32:31

这类似于Java 中int之间的区别Integer

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

11.2.1 属性访问器
[...]
产生式 MemberExpression : MemberExpression [ Expression ] 计算如下:

  1. 评估成员表达式。
  2. 调用 GetValue(Result(1))。
  3. 评估表达。
  4. 调用 GetValue(Result(3))。
  5. 调用 ToObject(Result(2))。
  6. 调用 ToString(Result(4))。
  7. 返回一个 Reference 类型的值,其基对象是 Result(5),其属性名称是 Result(6)。


9.9 对象

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

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

除此之外,包装对象不是很有用。我不知道为什么他们在语言中。我宁愿他们不是。:)

好的,所以基本上 javascript 会在运行时自动将字符串值装箱到 String 对象上时调用方法吗?如果是这种情况,为什么它没有在规范中定义(如果是并且我错过了它,我在哪里可以找到它?)?
2021-03-15 15:32:31
拳击可能是一个很好的类比,尽管 JavaScript 引擎肯定会以某种方式优化这种区别,因此它不会影响性能。
2021-03-24 15:32:31
intIntegerJava 中之间的区别并不相似int是一个原始类型,并且Integer是一个类。虽然自动装箱通常会消除较新版本的 Java 中的明显区别,但 Javascript 中没有原始字符串类型。
2021-03-28 15:32:31
在少数情况下,这种区别可能会被优化掉,但大多数 String 对象对性能不利,您应该避免使用它们。
2021-04-01 15:32:31
Friedo,字符串在标准中被明确称为原始值。
2021-04-08 15:32:31