问题描述
所以这是一个哲学问题。
在 TypeScript 中,子节点可以是无父节点,因为 ChildNode.parentElement
和 ChildNode.parentNode
都有 null
类型选项。
但是作为子节点,根据它的性质,它不是有一个父节点吗?我可以理解 parentElement
可能是 null
,因为它可能来自非元素节点(或者甚至可能),但至少 parentNode
不应该是非空的?
我知道 DOM spec 中并没有特别指明,但是 ChildNode
没有父级会不会很奇怪?
如果您可能将节点从父节点移开,是否是这样?但是这样的事情不会将 ChildNode
的类型更改为普通的 Node
吗?
我真的很想了解您对这个问题的见解,因为它让我有点困惑。
解决方法
来自https://developer.mozilla.org/en-US/docs/Web/API/ChildNode:
ChildNode
mixin 包含所有类型的 Node
对象通用的方法和属性,这些对象可以有一个父对象。它由 Element
、DocumentType
和 CharacterData
对象实现。
ChildNode 并不意味着“这个节点当前有一个父节点”。它只是其他类型实现的 mixin,以包含 remove()
、before()
、after()
和 replaceWith()
方法。
继承自 Node 但不混入 ChildNode 方法的类型的示例是 Document。 Document 是一个节点(它的子节点 parentNode
将是它自己)但它永远不能有父节点,因此 document.remove()
会产生编译错误。
如果您可能将节点从父节点移开,是否是这样?但是这样的事情不会将 ChildNode
的类型更改为普通的 Node
吗?
这不是 TypeScript 的静态类型检查的工作方式——在对象上调用 remove()
之类的方法不会改变其类型。 (技术上可能在 JavaScript 中更改对象的原型,但 TypeScript 不会对此进行建模。)该节点仍然是删除之前的同一类的对象,因此它仍然实现这些方法,即使在调用它们时节点没有父节点可能没有意义。事实上,由于 every Element is a ChildNode,在 element.remove()
之后动态改变类型是没有意义的,因为元素应该仍然是一个元素。