此问题来自another,它涉及console.dir
与字符串文字的行为。特别是,请参阅my answer上的评论。
众所周知,JavaScript中的String
个对象有很多方法。这些方法在String.prototype
对象上定义。例如String.prototype.toUpperCase
。因此,我们可以这样做:
var s = new String("hello"),
s2 = s.toUpperCase(); //toUpperCase is a method on String.prototype
但是,我们也可以这样做:
var s = "hello", //s is a string literal, not an instance of String
s2 = s.toUpperCase();
显然,当您在字符串文字上调用String.prototype
的方法时,JavaScript解释器正在进行某种形式的转换/转换。但是,我无法在spec中找到对此的任何引用。
这是有道理的,因为否则你必须明确地将每个字符串文字强制转换为String
对象,然后才能使用任何方法,这会非常烦人。
所以我的问题是,这个功能在哪里描述,我是否正确假设文字值暂时转换为String
的实例?我是否过度思考并忽略了一些明显的东西?
答案 0 :(得分:8)
这里定义:
当V为a时,GetValue使用以下[[Get]]内部方法 具有原始基值的属性引用。它被称为使用 base作为此值,属性P作为其参数。该 采取以下步骤:
- 设O为ToObject(base)。
- 设desc是调用属性名为P的O的[[GetProperty]]内部方法的结果。
- 如果未定义desc,则返回undefined。
- 如果IsDataDescriptor(desc)为true,则返回desc。[[Value]]。
- 否则,IsAccessorDescriptor(desc)必须为true,所以让getter为desc。[[Get]]。
- 如果未定义getter,则返回undefined。
- 返回调用getter提供base的[[Call]]内部方法的结果作为此值并且不提供任何参数。
醇>注意无法访问步骤1中可能创建的对象 在上述方法之外。实现可能会选择避免 实际创建的对象。这样的唯一情况 使用此内部方法的实际属性访问可以显示 效果是它调用访问器函数。
来源: http://es5.github.com/#x8.7.1
在步骤1中将原始字符串值强制转换为对象。
示例1
var str = 'some string';
str = str.toUpperCase();
这里,表达式str.toUpperCase
是根据11.2.1 Property Accessors中定义的语义进行评估的:
str
(请参阅10.2.2.1 GetIdentifierReference)。结果是一个引用,其基值是当前词法环境的环境记录,其引用名称为"str"
。此引用是 baseReference 。GetValue(baseReference)
确定的。由于 baseReference 不是属性引用(其基值不是对象或原始值,而是环境记录),因此调用GetBindingValue()
方法以检索值的参考。此方法返回局部变量str
的值,即原始字符串值'some string'
。该值为 baseValue 。'toUpperCase'
。 (为简单起见,我稍微缩短了这个过程。)因此,此过程涉及两个参考:
str
(基值:环境记录,引用名称:'str'
)str.toUpperCase
(基值:'some string'
,引用名称:'toUpperCase'
)最后,在后一个引用上执行调用操作符()
。该引用的值是根据本答案顶部定义的语义确定的。
示例2
var str = 'some string'.toUpperCase();
这里,表达式'some string'.toUpperCase
根据与示例1中相同的“Property Accessor”语义进行评估:
'some string'
显然评估为原始字符串值'some string'
。这是 baseReference 。 (不要让名称混淆你 - 这是一个字符串值,而不是引用。)GetValue(baseReference)
确定的。由于 baseReference 不是引用,因此该方法只返回参数值,即 baseValue = baseReference 。如您所见,就像示例1中一样, baseValue 是原始字符串值'some string'
。步骤3和4等同于示例1中的步骤3和4。
因此,标识符引用str
和字符串文字'some string'
都计算为相同的值 - 原始字符串值'some string'
- 并且该值用作 baseValue 用于新引用,然后使用()
调用。由于此引用具有原始基值,因此在我的答案开头定义的语义适用。
答案 1 :(得分:2)
这正是它正在做的事情。
根据需要使用Javascript boxes
原始类型。
以下是更多信息:
http://princepthomas.blogspot.com/2011/07/auto-boxing-javascript-primitive-types.html
答案 2 :(得分:1)
每the reference个文字转换为对象:
字符串文字(用双引号或单引号表示)和字符串 在非构造函数上下文中从String调用返回(即,没有 使用new关键字)是原始字符串。 JavaScript自动 转换基元和String对象,以便可以使用它 原始字符串的字符串对象方法。
答案 3 :(得分:0)
你几乎是对的。有一种称为自动装箱(在对象中包裹原语)http://princepthomas.blogspot.com/2011/07/auto-boxing-javascript-primitive-types.html
编辑:sory复制Mike Christensen链接 - 我没有注意到它。