0

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

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}
4

3 回答 3

2

this始终在范围(*)的上下文中引用对象。例如,您需要调用以从中获取伪原始值.toString()

return this.toString();

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


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

于 2013-04-01T13:00:36.073 回答
0

原始字符串值String对象之间存在差异。

'foo'             // primitive

new String('foo') // object

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

因此,inremoveExtensionthis一个String对象。另一方面,内置函数this.substr返回一个原语;这就是它的定义。因此,当您返回this( String object ) 与this.substr(string original ) 的结果时,您会看到不同的东西。如果要返回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. 如果功能码是严格码,设置ThisBindingthisArg.
  2. 否则,如果 thisArg 为 null 或未定义,则将 设置ThisBinding为全局对象。
  3. 否则,如果Type(thisArg)不是 Object,则将 设置ThisBindingToObject(thisArg)
  4. ……

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

于 2013-04-01T13:08:22.840 回答
0

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

'image'.removeExtension();

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

要获取特定的字符,请使用 'image'.charAt(3); // G

于 2013-04-01T13:15:15.800 回答