【问题标题】:String.prototype.myFunction not returning a string?String.prototype.myFunction 不返回字符串?
【发布时间】:2013-04-01 12:57:31
【问题描述】:

为什么下面的代码没有正确返回 this?它应该只返回“图像”,而不是对象中的所有字母,不是吗?

String.prototype.removeExtension = function(){
    return (this.lastIndexOf('.') !== -1) ? this.substr(0, this.lastIndexOf('.')) : this;
}

'image.jpg'.removeExtension(); // returns 'image'

'image.png.jpg'.removeExtension(); // returns 'image.jpg'

'image'.removeExtension(); // returns String {0: "i", 1: "m", 2: "a", 3: "g", 4: "e", removeExtension: function}

【问题讨论】:

标签: javascript string this function-prototypes


【解决方案1】:

this 总是在 (*) 范围内引用 object。例如,您需要调用 .toString() 以从中获取伪 原始值

return this.toString();

如果您像这样返回this,它将引用当前调用的String-object 的当前实例。


(*)(唯一的例外是 ES5 严格模式,其中this 也可能引用undefined

【讨论】:

  • 这么简单?谢谢!但我不明白的是为什么 this.substr(...) 会返回一个字符串,因为我认为 substr 只适用于字符串,还是 substr() 在内部执行 this.toString() ?
  • @emma.fn2 差不多。当您调用"Hello".substr() 之类的名称时,原始值 会在内部转换为它们的对象表示。反过来,该方法将返回一个新的原始字符串值
  • "伪原始值" 在这种情况下,“伪”是什么意思?原始价值对我来说看起来很具体。或者您的意思是 JS 没有实际的原语(甚至“原语”字符串也继承自 String.prototype)?
  • @FabrícioMatté 是的,几乎是后者。当我们处理 primitive value 和它的 Objectified 表示时,它有点难以理解,因为 ECMAscript 会随意转换它。我想这就是我的意思。它仍然可能是错误的措辞,我不确定。
  • 我们完全可以理解,没问题。 =]
【解决方案2】:

这是正常行为,因为 String 不是 char 数组。所以

'image'.removeExtension();

将返回一个对象字符串,而不是 {0: "i", 1: "m", 2: "a", 3: ...

获取特定的字符使用 '图像'.charAt(3); // g

【讨论】:

    【解决方案3】:

    原始string valueString object 之间存在差异。

    'foo'             // primitive
    
    new String('foo') // object
    

    当您在字符串原语上调用 String 成员函数时,它会被包装在一个 String 对象中,该对象成为函数中 this 的值。 (下面有更多关于这种行为的信息。)

    所以,在removeExtension 中,this 是一个String 对象。另一方面,内置函数this.substr 返回一个原语;这就是它的定义。因此,当您返回 this (String object) 与 this.substr (string primitive) 的结果时,您会看到不同的东西。如果要返回this 对象的字符串原始版本,只需使用this.toString

    对于任何原语,您都会看到相同的包装行为,例如,Numbers:

    Number.prototype.returnThis = function() { return this; }
    
    typeof 2;               // 'number'
    typeof (2).returnThis() // 'object' (a Number object, specifically)
    

    如果您真的想知道为什么会发生这种情况,请参阅 ECMAScript 规范:

    10.4.3 输入功能码

    控制进入执行时执行以下步骤 函数对象 F 中包含的函数代码的上下文,调用者 提供了 thisArg,调用者提供了 argumentsList:

    1. 如果功能码为严格码,将ThisBinding设置为thisArg
    2. 否则,如果 thisArg 为 null 或未定义,请将 ThisBinding 设置为全局对象。
    3. 否则,如果Type(thisArg) 不是对象,则将ThisBinding 设置为ToObject(thisArg)
    4. ....

    第 3 点很重要:在原始值(即非对象)上调用函数会将它们强制转换为相应的对象形式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 2020-04-13
      • 2023-03-30
      • 2013-04-25
      • 2012-11-21
      相关资源
      最近更新 更多