草庐IT

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

coder 2025-02-19 原文

这个问题出自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/

有关javascript - 为什么 String.prototype 的方法可用于字符串文字?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  4. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  5. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  6. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  7. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  8. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  9. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  10. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

随机推荐