gpt4 book ai didi

javascript - 为什么 String.prototype 的方法可用于字符串文字?

转载 作者:数据小太阳 更新时间:2023-10-29 05:53:08 26 4
gpt4 key购买 nike

这个问题出自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 的实例是否正确?我是不是想多了,漏掉了一些明显的东西?

最佳答案

定义在这里:

The following [[Get]] internal method is used by GetValue when V is a property reference with a primitive base value. It is called using base as its this value and with property P as its argument. The following steps are taken:

  1. Let O be ToObject(base).
  2. Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
  3. If desc is undefined, return undefined.
  4. If IsDataDescriptor(desc) is true, return desc.[[Value]].
  5. Otherwise, IsAccessorDescriptor(desc) must be true so, let getter be desc.[[Get]].
  6. If getter is undefined, return undefined.
  7. Return the result calling the [[Call]] internal method of getter providing base as the this value and providing no arguments.

NOTE The object that may be created in step 1 is not accessible outside of the above method. An implementation might choose to avoid the actual creation of the object. The only situation where such an actual property access that uses this internal method can have visible effect is when it invokes an accessor function.

来源: http://es5.github.com/#x8.7.1

原始字符串值在步骤 1 中被强制转换为一个对象。


示例 1

var str = 'some string';
str = str.toUpperCase();

此处,表达式 str.toUpperCase 是根据 11.2.1 Property Accessors 中定义的语义求值的。 :

  1. 标识符 str 根据标识符解析进行评估(参见 10.2.2.1 GetIdentifierReference )。结果是一个引用,其基值为当前词法环境的环境记录,引用名称为 "str"。此引用是 baseReference
  2. baseValue 通过执行 GetValue(baseReference) 确定.由于 baseReference 不是属性引用(它的基值不是对象或原始值,而是环境记录),GetBindingValue()调用方法以检索引用的值。此方法返回局部变量 str 的值,即原始字符串值 'some string'。此值为 baseValue
  3. propertyNameValue 的计算结果为原始字符串值 'toUpperCase'。 (为了简单起见,我稍微缩短了这个过程。)
  4. 创建了一个新引用,其基值为 baseValue,引用名称为 propertyNameValue

所以,这个过程涉及到两个引用:

  • str(基值:环境记录,引用名称:'str')
  • str.toUpperCase(基值:'some string',引用名称:'toUpperCase')

最后,调用操作符()在后面的引用上执行。该引用的值根据此答案顶部定义的语义确定。

示例 2

var str = 'some string'.toUpperCase();

此处,表达式 'some string'.toUpperCase 根据与示例 1 中相同的“属性访问器”语义进行评估:

  1. 字符串文字 'some string' 显然求值为原始字符串值 'some string'。这是 baseReference。 (不要让名称混淆 - 这是一个字符串值,而不是引用。)
  2. baseValue 通过执行 GetValue(baseReference) 确定。由于 baseReference 不是引用,该方法只返回参数值,即 baseValue = baseReference

如您所见,与示例 1 一样,baseValue 是原始字符串值 'some string'。步骤3和4等同于示例1中的步骤3和4。

因此,标识符引用 str 和字符串文字 'some string' 的计算结果相同 - 原始字符串值 'some string' - 该值用作新引用的 baseValue,然后用 () 调用。由于此引用具有原始基值,因此我的回答开头定义的语义适用。

关于javascript - 为什么 String.prototype 的方法可用于字符串文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8581874/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com