JavaScript中能否扩展原始类型类?如何构造后返回原始值?
关于扩展原始类型构造函数的问题
核心原因:new调用原始类型构造函数返回包装对象
用new String()、new Number()或者你自定义的new Name()得到的都是包装对象,而非原始值。原始值(比如""、0)是基本类型,而包装对象属于object类型,所以严格相等===必然返回false——因为类型都不一样。
无法让自定义类new后直接返回原始值
ES6类的构造函数规则是:如果返回的是对象,会覆盖默认的实例返回;但如果返回原始值,会直接被忽略,最终还是返回类的实例(也就是包装对象)。比如你在Name的构造函数里写return "",new Name()依然会返回Name的实例,而非原始字符串。
解决你的字典使用需求的几种方案
方案1:用工厂函数替代构造函数存入字典
放弃用new调用,直接存返回对应值的工厂函数,这样能直接得到原始值:
const dict = { "point": () => new Point(), "area": () => new Area(), "string": () => String(), // 直接返回原始空字符串"" "name": () => "", // 自定义Name逻辑,直接返回原始字符串 "number": () => Number(), // 返回原始数字0 } const string = dict["string"]() string === "" // true
方案2:获取实例后手动转换为原始值
如果必须保留new调用的方式,可以通过valueOf()或toString()方法把包装对象转为原始值:
const string = new dict["string"]().valueOf() string === "" // true const number = new dict["number"]().valueOf() number === 0 // true
方案3:重写自定义类的转换方法(仅支持松散相等)
如果你的场景可以接受松散相等==,可以在自定义类里重写valueOf或toString方法,让对象在需要时自动转换为原始值:
class Name extends String { valueOf() { return "" } toString() { return "" } } const name = new Name() name == "" // true(松散相等会触发转换) name === "" // 依然false(严格相等不做类型转换)
内容的提问来源于stack exchange,提问作者Maddin
相关产品推荐
相关产品推荐

