Javascript String.prototype.myFunction是否不返回字符串?

Javascript String.prototype.myFunction是否不返回字符串?,javascript,string,this,function-prototypes,Javascript,String,This,Function Prototypes,为什么下面的代码不能正确地返回这个?它应该只返回“image”,而不是一个对象中的所有字母,不是吗 String.prototype.removeExtension = function(){ return (this.lastIndexOf('.') !== -1) ? this.substr(0, this.lastIndexOf('.')) : this; } 'image.jpg'.removeExtension(); // returns 'image' 'image.pn

为什么下面的代码不能正确地返回这个?它应该只返回“image”,而不是一个对象中的所有字母,不是吗

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}

始终引用作用域(*)上下文中的对象。例如,您需要调用
.toString()
,从中获取伪原语值

return this.toString();
如果像那样返回
this
,它将引用当前调用的
String对象的当前实例



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

原语和

当您在字符串原语上调用字符串成员函数时,它将被包装在字符串对象中,该对象将成为函数中
this
的值。(有关此行为的详细信息,请参见下文。)

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

您可以在任何原语中看到相同的包装行为,例如,
Number
s:

Number.prototype.returnThis = function() { return this; }

typeof 2;               // 'number'
typeof (2).returnThis() // 'object' (a Number object, specifically)
如果您真的想知道为什么会发生这种情况,请参阅ECMAScript规范:

10.4.3输入功能代码

当控件进入执行时,将执行以下步骤 函数对象F(调用方)中包含的函数代码的上下文 提供此参数,以及调用者提供的参数列表:

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

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

    这是一种正常行为,因为字符串不是字符数组。因此

    'image'.removeExtension();
    
    将返回一个对象字符串,而不是{0:“i”、1:“m”、2:“a”、3:

    要获得特定的字符,请使用
    “image”.charAt(3);//g

    this.toString()
    )这么简单?谢谢!但我不明白的是为什么这个.substr(…)会返回一个字符串,因为我认为substr只对字符串有效,或者substr()会这样做。toString()内部?@emma.fn2差不多。当您调用类似于
    “Hello.substr()
    ”的东西时,基本值在内部会转换为它们的对象表示形式。“伪基本值”是什么意思在这种情况下?原语值在我看来非常具体。或者你是说JS没有实际的原语(因为即使是“原语”字符串也继承自
    String.prototype
    )?@Fabrício Matté是的,基本上是后者。当我们处理一个原始值和它的对象化表示时,这有点难以理解,因为ECMAscript会在引擎盖下随意转换它。我想这就是我的意思。它可能仍然是错误的措辞,我不确定。我们可以完全理解,没有问题。
    =]
    'image'.removeExtension();