是否可以向String
实例添加方法,例如
x = "123"
x.method = function() { console.log("test") }
x.method()
是否可以向String
实例添加方法,例如
x = "123"
x.method = function() { console.log("test") }
x.method()
是的,你可以做到。但是,您必须首先获取字符串原语并将其设为字符串实例:
x = new String("123");
x.method = function() { console.log("test") };
x.method();
JavaScript 既有字符串原语,也有字符串实例。在您的原始代码中,当您编写时:
x.method = ...;
...从变量中检索字符串原语x
并提升为字符串实例,您将方法添加到该实例,但由于字符串实例从未存储回x
变量,因此当您尝试调用它时该方法不存在. (是的,这是违反直觉的。)
通过new String(...)
在上面使用,我实际上得到了字符串实例并将其存储在x
. 然后,由于它是一个合适的对象,我可以向它添加属性。
您还可以向 中添加方法String.prototype
,如下所示:
String.prototype.capitalize = function() {
return this.substring(0, 1).toUpperCase() + this.substring(1);
};
console.log("testing".capitalize()); // "Testing"
有些人认为这是不好的做法。其他人说这正是我们拥有原型继承的原因,因此我们可以使用原型来增强事物。虽然我从未见过人们增强的任何问题,但当人们增强时String.prototype
我似乎Array.prototype
遇到了问题(因为人们坚持误用for-in
)和Object.prototype
.
字符串和数字是自动装箱的原语,这意味着当您对它们执行 OO 操作时,它们会被强制转换为“String”和“Number”类,但随后会立即取消装箱。
您的代码评估为:
x = "123"
(new String(x)).method = function() { console.log("test") }
(new String(x)).method() // Error
Your second call is failing because you are dealing with an entirely different String object. As T.J. stated, you can get around this by making x
a String object, but this is not a common or recommended practice.
You can extend all strings by adding the method to String.prototype
:
x = "123"
String.prototype.method = function() { console.log("test") }
x.method()
This call evaluates the same way as (new String(x)).method()
but since that method exists in the prototype, it will get called.
You could define new properties using ECMA5
Object.defineProperty(String.prototype, "test", {
value: function test() { console.log('test:',this) },
configurable: true,
enumerable: false,
writeable: true
});
See the complete answer: Extending core types without modifying prototype