Js使用原型链对对象进行扩展

在C#的扩展方法中,我们了解到了一种不需要修改源对象定义即可为对象添加新的行为的方法,在JavaScript中,我们通过原型链也可以实现类似的效果,为对象添加新的行为。需要一定的Js原型链基础。

原型链

简单介绍一下原型链,在C#语言中,有类的概念,所有的OOP(封装,继承,多态)都是基于类来实现的。但在Js中,没有类的概念,所有的对象都有一个继承的原型对象,层层向上,直到原型对象为null。可以查看MDN文档

使用原型来扩展对象

类似于C#扩展方法,下面就从Date对象入手,Date在开发中使用非常频繁,但对于Js原生Date对象,直接打印的结果非常不直观。下面,给Date加上一个format方法,实现简单的格式化,传入一个格式化字符串,传出一个时间字符串。

直接上代码,通过匹配格式化字符串中的字符,再替换成对应的时间元素,最后组合传出。

Date.prototype.format = function(fmt)
{
    const o = {
        'M+': this.getMonth() + 1,                 // 月份
        'd+': this.getDate(),                    // 日
        'H+': this.getHours(),                   // 小时(12)
        'h+': this.getHours() > 12 ? this.getHours() - 12 : this.getHours(),     //小时(24)
        'm+': this.getMinutes(),                 // 分
        's+': this.getSeconds(),                 // 秒
        'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
        'S': this.getMilliseconds()             // 毫秒
    };
    if (new RegExp('(y+)').test(fmt))
    {
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    const keys = Object.keys(o);
    const values = Object.values(o);
    for (let i = 0; i < keys.length; i++)
    {
        if (new RegExp(`(${ keys[i] })`).test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (values[i].toString())
            : ((`00${ values[i]}`).substr(('' + values[i].toString()).length)));
    }
    }
    return fmt;
};

使用起来也是很方便,直接传入一个格式化字符串即可。

let time = new Date();
console.log(time.format('yyyy-MM-dd HH:mm:ss'));
console.log(time.format('yyyy-MM-dd hh:mm:ss'));
console.log(time.format('MM-dd HH:mm'));

// 输出  
// 1997-11-03 15:30:00
// 1997-11-03 03:30:00
// 11-03 15:30
发布时间:2021-06-23