相比于使用传统的Object实现补环境框架结构,使用 ES6 的 Class 具有以下优势:
- 代码维护更方便:Class的语法更简洁直观,方便开发者阅读和维护。
- 组织结构更清晰:Class提供了明确的层次结构,有助于代码的模块化管理。
- 扩展性更强:Class的继承机制使得扩展功能变得更加容易和自然。
- 代码复用率更高:通过继承和方法重用,Class大大提高了代码的复用性。
- 继承能力强:Class的继承机制远超传统Object,使得复杂对象的创建和管理更加高效。
- 减少重复代码:使用Class避免了传统Object方式中大量重复代码的编写。
- 贴近浏览器实现:Class的形式更接近浏览器底层实现,在数据输出上具有特别的优势。
以下是遵循跟浏览器保持一致的 document 继承结构
javascript
Object
└─ EventTarget
└─ Node
└─ Element
└─ HTMLElement
└─ HTMLDivElement
└─ ... (其他HTML元素)
└─ Document
└─ HTMLDocument
以下为框架代码的实现
javascript
class EventTarget {
// 所有能够监听和触发事件的对象的基类,为 DOM 中的各种元素(如 Node、Element、HTMLElement 等)提供了统一的事件处理接口,使得这些对象可以响应用户交互和其他事件
constructor () {
this.listeners = {}
}
addEventListener (type, callback) {
if (!this.listeners[type]) {
this.listeners[type] = []
}
this.listeners[type].push(callback)
}
removeEventListener (type, callback) {
if (!this.listeners[type]) return
const stack = this.listeners[type]
for (let i = 0; i < stack.length; i++) {
if (stack[i] === callback) {
stack.splice(i, 1)
return
}
}
}
dispatchEvent (event) {
if (!this.listeners[event.type]) return true
const stack = this.listeners[event.type].slice()
for (let i = 0; i < stack.length; i++) {
stack[i].call(this, event)
}
return !event.defaultPrevented
}
}
class Node extends EventTarget {
// 提供了基本的树结构操作和与节点相关的功能,所有的 DOM 元素和文本节点等都继承自Node
constructor () {
super()
}
}
class Element extends Node {
// 这个类里面放的是所有元素的Element类的属性方法和HTMLElement的属性方法,这里将 HTMLElement 的属性方法全部合并到Element中了
constructor () {
super()
}
}
class HTMLElement extends Element {
constructor () {
super()
}
}
// 一些内置的元素,比如div是来自于HTMLDivElement这个类实例化出来的
class HTMLDivElement extends HTMLElement {
constructor () {
super()
}
// 添加特有的属性和方法
}
// 一些自定义的元素名,他就会用HTMLUnknownElement这个类实例化出来
class HTMLUnknownElement extends HTMLElement {
constructor(tagName) {
super()
this.tagName = tagName
}
// 添加特有的属性和方法
}
class Document extends Node {
constructor () {
super()
}
createElement (tagName) {
switch (tagName.toLowerCase()) {
case 'div':
return new HTMLDivElement()
default:
return new HTMLUnknownElement(tagName)
}
}
}
class HTMLDocument extends Document {
constructor () {
super()
}
}
const document = new HTMLDocument()
console.log(document)