JavaScript原型与原型链的实际业务应用

147 阅读3分钟

前言

每次面试都在解答一堆原型与原型链的问题,又是prototype,又是_prototype_,那么问题来了,你们究竟有没有真的把这个知识点应用在项目中呢?还是单纯的背八股文。

反正几年前的我就是真的只是背八股文的,也就这两年才开始真正的用起来。那么下面让我用3个小例子带大家一起去使用起来。

例子1:金额显示

对于金额的显示,我们会经常需要将1234567.89显示成1,234,567.89这样,普通的写法,可能就是写个工具函数来转换一下,但是!这个功能使用率其实是非常高的,如果每次都引用一个工具函数来做这个功能,会很麻烦,这时候我们可以在入口文件里面,在数字的原型上添加这个工具函数,后续就会使用起来很方便了。

Number.prototype.toAmount = function (): string {
    return this.toLocaleString('en-US', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
    })
}

let a = 1234567.89
a.toAmount() //1,234,567.89

我们在Number的原型(prototype)上拓展一个方法toAmount,它的使用方法跟toFixed是一样的,这样能极大的减少我们的工作量。

这里有几个技术点,第一,为什么不用箭头函数?好,大家跟我一起来背3次箭头函数跟普通函数的区别,this的指向,箭头函数的this指向外层作用域,通常是undefined,而普通函数是调用该方法的数字实例。所以,所有写在原型上的方法,都只能用普通函数来写。

第二,有没有发现: string这个东西,对,这是ts的东西,现在新项目用ts的越来越多了,如果想要有对应的提示,那么我们得在一个全局类型里面补充对应的类型。不过不同配置有不同写法,大体都是这样写的。

declare global {
    interface Window {
    }
    interface Number {
        toAmount(): string //数字加逗号格式化
        formatSign(isToAmount = false): string //数字返回正反
    }
    interface String {
        toBoolean(): boolean
    }
   
}

第三,toLocaleString,额,这个自己百度一下吧。这个是原生方法来的。

例子2:数字的正负号显示

众所周知,正数是不会显示+号的,而我们有很多场景是需要这个+号的,这种情况,我们也可以在原型链拓展方法,上面的类型也有提示给大家了,下面我给大家来展示一下代码

Number.prototype.formatSign = function (isToAmount = false): string {
    const numericValue = this.valueOf()

    if (numericValue === 0) return '0'

    let value: string
    if (isToAmount) {
        value = this.toAmount()
    } else {
        value = Math.abs(numericValue).toString()
    }

    return numericValue > 0 ? `+${value}` : `-${value}`
}

//输出:
// 正数 → "+value"
// 负数 → "-abs(value)" 
// 零 → "0" (特殊处理,不加符号)

对,既然它是个方法,也是能传参的,这样我们就能有不同的输出了,看到toAmount了没,就是上面的,我们能在这里加入各种各样的方法,当然,不能加太复杂的,它会一直挂在原型上,占着内存。

例子3:字符串转布尔值

为什么会出现这样的需求呢?直接去判断不行?这就得问一下我们的好后端了,返回个字符串的null或者其他东西,下面直接看代码

String.prototype.toBoolean = function (): boolean {
    const falseValues = ['false', '0', '', 'null', 'undefined']
    return !falseValues.includes(this.toLowerCase())
}

falseValues可以拓展一下,出现这样的功能其实是有点奇怪,不过做个例子倒是还可以,字符串“0”,如果直接拿去判断,是为true的,用这个转一下,就可以变成false了。

结语

这几个只是简单的应用,我们还能在一些复杂的原型上加各种各样的方法,像object上加一些获取key的数量之类的,或者其他对象上,加入原型方法,这种就看你们这个方法的复用度了,由你们自己去判断要不要加了。好了,再见!