Javascript向String实例添加方法

时间:2013-03-29 22:02:13

标签: javascript

是否可以向String实例添加方法,例如

x = "123"
x.method = function() { console.log("test") }

x.method()

3 个答案:

答案 0 :(得分:3)

是的,你可以做到。您必须首先获取字符串原语并使其成为字符串 instance ,但是:

x = new String("123");
x.method = function() { console.log("test") };

x.method();

JavaScript既有字符串原语,也有字符串实例。在您的原始代码中,当您写下:

x.method = ...;

...从变量x检索字符串原语并将其提升为您添加方法的字符串实例,但由于字符串 instance 从未存储回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时(因为人们坚持misuing for-in)和{{ 1}}。

答案 1 :(得分:3)

字符串和数字是自动编排的原语,这意味着当您对它们执行OO操作时,它们将被转换为“字符串”和“数字”类,但随后会立即取消装箱。

您的代码评估为:

x = "123"
(new String(x)).method = function() { console.log("test") }

(new String(x)).method() // Error

您的第二次调用失败,因为您正在处理完全不同的String对象。作为T.J.声明,你可以通过使x成为一个String对象来解决这个问题,但这不是常见或推荐的做法。

您可以通过将方法添加到String.prototype来扩展所有字符串:

x = "123"
String.prototype.method = function() { console.log("test") }

x.method()

此调用的计算方式与(new String(x)).method()相同,但由于该方法存在于原型中,因此将调用它。

答案 2 :(得分:1)

您可以使用ECMA5

定义新属性
Object.defineProperty(String.prototype, "test", {
value: function test() { console.log('test:',this) },
  configurable: true,
  enumerable: false,
  writeable: true
});

查看完整答案: Extending core types without modifying prototype