扩展:内置对象添加方法
JavaScript 由于是动态语言,所以我们可以实时的为对象添加属性和方法,甚至是 JavaScript 中的内置的对象,我们也可以很轻松的为其添加更多的属性和方法,从而带来更多的功能。
这种做法往往被称之猴子补丁(monkey-patching)。
不过,尽管这是一项非常强大的技术,但是 JavaScript 社区的大部分人都不推荐这么做,大部分人的观点是"别耍流氓,不是你的对象别动手动脚"。
下面我们来举一个例子,给 Number 这个内置对象的原型添加isOdd()
和isEven()
方法,如下:
Number.prototype.isEven = function () {
return this % 2 === 0;
}
Number.prototype.isOdd = function () {
return this % 2 === 1;
}
const i = 42;
console.log(i.isEven()); // true
const j = 13;
console.log(j.isOdd()); // true
可以看到,当我们在 Number 的原型上添加了 2 个方法后,所有的数字类型的值都可以使用这 2 个方法。
在 JavaScript 中,有些方法规范中有,但是部分浏览器并不支持。比如,String.prototype 中的trim()
方法,这是个所有字符串都会继承的方法,它能够删除字符串开头和结尾的所有空白。
但是不幸的是,Internet Explorer 8 及以下版本并没有实现该方法。这个时候我们就可以使用猴子补丁来进行添加。
String.prototype.trim = String.prototype.trim || function () {
return this.replace(/^\s+|\s+$/, '');
}
console.log(" hello ".trim().length); // 5
在上述的代码中,如果trim()
方法存在,就用内置的 String.prototype.trim,否则就用猴子补丁提供的函数对 String 的原型添加该方法。
虽然对内置对象添加猴子补丁看似是一种解决遗漏功能的好办法,但是它也有可能带来不可预期的行为。
目前 JavaScript 社区的共识为:不应该这样做。所以除非有很好的理由,否则应该避免给任何内置对象添加猴子补丁。如果我们添加的方法后面被语言原生实现了,就会出现更多的问题。
避免引起问题的另一种方式使用 extends 子类化一个已经创建好了的类,从而创建自己的类。例如,我们可以像下面一样,通过继承内置的 Number 类来创建自己的 Number 类,如下:
class myNum extends Number {
constructor(...args) {
super(...args);
}
isEven() {
return this % 2 === 0
}
}
const i = new myNum(42);
// 无论是新类添加的方法还是 Number 类里面的方法都可以使用
console.log(i.isEven()); // true
console.log(i.toFixed(2)); // 42.00
Comments