javascript字符串类型和字符串对象之间的差异?

javascript字符串类型和字符串对象之间的差异?,javascript,Javascript,我一直在摆弄ECMA-262标准(ECMAScript语言规范,第三版,如果这与此有关的话-我没有发现第三版和第五版在字符串类型/字符串对象上有任何区别) 有一件事让我困惑:字符串类型和字符串对象之间的区别。是的,我知道字符串类型是一个16位UTF-16单元的序列,字符串对象是一个内置对象,其内部类属性设置为“String”,其内部值属性设置为字符串类型的值 但是阅读规范时,字符串类型似乎没有公开任何方法;也就是说,它只是一个没有任何附加属性的值。以这段代码为例,一切都完全符合预期: docum

我一直在摆弄ECMA-262标准(ECMAScript语言规范,第三版,如果这与此有关的话-我没有发现第三版和第五版在字符串类型/字符串对象上有任何区别)

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

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

document.writeln(typeof "foo"); // 'string'
document.writeln(typeof new String("foo")); // 'object'
第一种类型是实际的字符串类型,第二种类型是对象类型(它是String类的对象,但其数据类型是Object)。然而,看看这个:

"foo".charAt(0);

fooStrObj = new String("Foo");
fooStrObj.charAt(0);
它们似乎都公开了相同的函数,但在ECMA-262标准中定义的字符串类型上没有函数;它公开的所有函数都来自String.prototype对象(我看不到任何关于String类型神奇地公开ECMA-262标准中String.prototype对象的所有属性和函数的引用)。那么,字符串类型的值是否会自动升级为字符串对象,并将原始字符串类型值作为其内部值属性


如果它们被视为完全相同的(无论出于何种目的,它们似乎都是相同的),为什么有两种不同的方式来表示字符串呢?

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

根据标准,当您尝试调用方法时,字符串会自动转换为
String
对象。看见步骤5调用
对象
(定义见第9.9节)

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

  • 计算成员表达式
  • 调用GetValue(结果(1))
  • 计算表达式
  • 调用GetValue(结果(3))
  • 调用ToObject(结果(2))
  • 调用ToString(结果(4))
  • 返回一个类型为Reference的值,其基本对象为Result(5),属性名称为Result(6)

  • 9.9 ToObject

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

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


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

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

    区分差异的简单方法是(在浏览器中)

    另外

    "foo" == new String("foo")
    
    如果为true,则仅由于==运算符的隐式类型转换才为true

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

    将失败。

    Ok,所以基本上javascript会在运行时调用方法时自动将字符串值框到字符串对象?如果是这种情况,为什么不在规范中定义它(如果是,我错过了它,我在哪里可以找到它?)?它与Java中的
    int
    Integer
    之间的区别并不相似
    int
    是一个基本类型,
    Integer
    是一个类。虽然自动装箱通常会消除较新版本Java中的明显区别,但Javascript.friedo中没有基元字符串类型,字符串在标准中显式称为基元值。装箱可能是一个很好的类比,虽然JavaScript引擎以某种方式优化了这种区别,因此不会影响性能。这种区别在少数情况下可能会被优化,但大多数字符串对象对性能有害,您应该避免使用它们。谢谢,这是我有点怀疑的,你能告诉我,在实际的规格中,它在哪里这样说吗。如果您在心里一步一步地完成它,您将在第20步结束对字符串对象调用ToPrimitive;最后调用了它的
    .toString()
    方法。非常感谢,伙计!学到了一些新东西,你帮了我很多+1字符串原语和字符串对象之间的区别:一个非常重要的区别是
    新字符串(“”
    是真实的。是的,这是一个好问题,我从阅读中学到了一些新东西+1另见
    "foo" === new String("foo")