【JS】扩展内建类 - Symbol.species
Symbol.species 是个函数值属性,其被构造函数用以创建派生对象,
Symbol.species访问器属性允许子类覆盖对象的默认构造函数。
JS内建类可以被扩展
class MyArray extends Array {
isEmpty(){
return this.length === 0
}
}
const arr = new MyArray(1,2,3,4,5)
console.log(arr.isEmpty()); // false
const newArr = arr.filter(item => item > 3)
console.log(newArr.length,newArr.isEmpty()); 2,false
我们可以发现当 arr.filter()
被调用时,它的内部使用的是 arr.constructor
来创建新的结果数组,而不是使用原生的 Array
。因此我们可以在结果数组上继续使用 MyArray
的方法。
我们可以给这个类添加一个特殊的静态 getter Symbol.species
。如果存在,则应返回 JavaScript 在内部用来在 map
和 filter
等方法中创建新实体的 constructor
。
class MyArray extends Array {
isEmpty(){
return this.length === 0
}
static get [Symbol.species](){
return Array
}
}
const arr = new MyArray(1,2,3,4,5)
console.log(arr.isEmpty()); // false
const newArr = arr.filter(item => item > 3)
console.log(newArr.length,newArr.isEmpty()); // newArr.isEmpty is not a function
这时,arr.filter()
创建的数组对象是使用Array
创建的,所以不能使用MyArray.prototype
上的方法。
内建类的静态方法不能被继承
内建对象有它们自己的静态方法,例如 Object.keys
,Array.isArray
等。
通常,当一个类扩展另一个类时,静态方法和非静态方法都会被继承。但内建类却是一个例外。它们相互间不继承静态方法。
下图中,Array
和 Date
都继承自 Object
,所以它们的实例都有来自 Object.prototype
的方法。但 Array.[[Prototype]]
并不指向 Object
,所以它们没有例如 Array.keys()
(或 Date.keys()
)这些静态方法。
与普通类的继承相比,内建类之间的extends只创建了一个[[Prototype]]引用,Child.[[prototype]] = Parent.prototype
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现