【问题标题】:Difference between the javascript String Type and String Object?javascript字符串类型和字符串对象之间的区别?
【发布时间】:2010-01-12 19:43:58
【问题描述】:

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

有一件事让我感到困惑:字符串类型和字符串对象之间的区别。是的,我知道 String Type 是 16 位 UTF-16 单元序列和 String Object 是一个内置对象的区别,它的内部Class 属性设置为“String”,其内部 Value 属性设置为 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 对象(我看不到 String Type 神奇地公开了 ECMA 中 String.prototype 对象的所有属性和函数的事实- 262 标准)。 String Type 类型的值也会自动提升为 String Object,并将原始 String Type 值作为其内部 Value em> 属性?

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

【问题讨论】:

标签: javascript


【解决方案1】:

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

会失败。

【讨论】:

  • 谢谢,这是我有点怀疑的,你能指出实际规范中的哪个地方是这样说的吗?
  • bclary.com/2004/11/07/#a-11.9.3。如果您在脑海中逐步完成它,您将在第 20 步结束对 String 对象调用 ToPrimitive;最终调用它的.toString() 方法。
  • 非常感谢朋友!学到了一些新东西,你帮了我很多。 :) +1
  • 字符串原语和字符串对象的区别:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 一个非常重要的区别是new String("") 是真实的。
【解决方案2】:

这类似于Java中intInteger之间的区别。

根据标准,当您尝试调用方法时,字符串会自动转换为String 对象。见ECMA 262-3 section 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(Result(2))。
  6. 调用 ToString(Result(4))。
  7. 返回一个 Reference 类型的值,其基对象为 Result(5),其属性名称为 Result(6)。


9.9 目标对象

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

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

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

【讨论】:

  • 好的,所以基本上javascript会在运行时自动将字符串值装箱到String对象上,当方法被调用时?如果是这种情况,为什么规范中没有定义(如果是,我错过了,我在哪里可以找到它?)?
  • 这与Java中intInteger之间的区别并不相似。 int 是原始类型,Integer 是类。虽然自动装箱通常会消除较新版本 Java 中的明显区别,但 Javascript 中没有原始字符串类型。
  • friedo,字符串在标准中被明确称为原始值。
  • 装箱可能是一个很好的类比,尽管这种区别肯定会被 JavaScript 引擎以某种方式优化掉,因此不会影响性能。
  • 这种区别在少数情况下可能会被优化掉,但大多数 String 对象对性能不利,您应该避免使用它们。
猜你喜欢
  • 2011-03-18
  • 2017-01-29
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 2013-06-19
相关资源
最近更新 更多