为什么下面的代码没有正确返回这个?它应该只返回'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}
答案 0 :(得分:2)
this
始终在范围(*)的上下文中引用对象。例如,您需要调用.toString()
来获取伪原始值。
return this.toString();
如果您再次返回this
,则会引用当前调用的String-object
的当前实例。
(*)(唯一的例外是ES5严格模式,其中this
也可能引用undefined
值
答案 1 :(得分:0)
原始string value和String
object之间存在差异。
'foo' // primitive
new String('foo') // object
当您在字符串基元上调用String成员函数时,它将被包装在String对象中,该对象将成为函数中this
的值。 (以下有关此行为的更多信息。)
因此,在removeExtension
中,this
是String
个对象。另一方面,内置函数this.substr
返回一个原语;这就是它的定义方式。因此,当您返回this
(String
对象)与this.substr
(字符串 primitive )的结果时,您会看到不同的内容。如果要返回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中包含的函数代码的上下文,一个调用者 提供thisArg,并且调用者提供了argumentsList:
- 如果功能代码是严格代码,请将
ThisBinding
设置为thisArg
。- 否则,如果thisArg为null或未定义,请将
ThisBinding
设置为全局对象。- 如果
Type(thisArg)
不是对象,请将ThisBinding
设置为ToObject(thisArg)
。- ....
醇>
点#3是重要的:在原始值上调用函数(即非对象)将它们强制转换为相应的对象形式。
答案 2 :(得分:0)
这是正常行为,因为String不是char数组。所以
'image'.removeExtension();
将返回不是{0:“i”,1:“m”,2:“a”,3:...
的对象字符串获取特定的char使用 “image'.charAt(3); // g