08月07, 2022

JS进阶(1)--对象(7)--扩展:内置对象添加方法

扩展:内置对象添加方法

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

本文链接:http://www.yanhongzhi.com/post/js_ap_7.html

-- EOF --

Comments