javascript - JavaScript:导入模块或向“文档”添加功能?
问题描述
我想用新方法扩展 vanilla DOM 对象,例如document.createElement()
通过定义一个新方法进行createElementWithAttrs()
扩展,或者扩展,Element
但以下两个中的哪一个是最佳实践?
方法 A
(就像Chrome DevTools 是如何做到的,但这可能是因为代码在 ES2015 之前很久就从 WebKit 继承了)
将新方法添加到现有的 DOM 类原型中。
// dom.js
Document.prototype.createElementWithClass = (tagName, className) => { ... };
Element.prototype.findEnclosingShadowRoot = () => { ... };
// probably a few more
// someScriptName.js
const e1 = document.createElementWithClass(...);
...
const shadow = e2.findEnclosingShadowRoot();
优点:
- 简洁直观,因为它们可以像原生 DOM 的一部分一样使用
缺点:
- 必须插入
dom.js
带有<script>
标签的 HTML - 有时会让读者感到困惑(包括我自己,因为时间长了我可能会忘记)。
方法 B:
在 ES 模块中定义它们。
// dom.js
export const createElementWithClass = (tagName, className) => { ... };
export const findEnclosingShadowRoot = (element) => { ... };
// probably a few more
// someScriptName.js
import * as dom from './dom.js';
const e1 = dom.createElementWithClass(...);
...
const shadow = dom.findEnclosingShadowRoot(e2);
优点和缺点与上面的“缺点”和“优点”相反。
有最佳实践吗?我是否缺少一些需要考虑的优点/缺点?谢谢。
解决方案
刚刚发现一篇深入的文章分析了为什么不推荐方法 A:http : //perfectkills.com/whats-wrong-with-extending-the-dom,那么要点是:
缺乏规范。该标准不要求
Document
和Element
和其他人被暴露。宿主对象没有规则(DOM 对象是宿主对象):它们的行为依赖于实现。
名称冲突。
性能开销。
浏览器中的错误,主要在 IE 和某些版本的 Safari 中。
推荐阅读
- opencv - OPENCV 中的线路端点检测
- django - 每次都需要运行makemessages吗?
- ruby-on-rails - 如何在分组选择中指定选定元素
- spring-boot - 通过参数对不同 Spring 控制器方法的顺序
- flutter - Flutter 条件渲染列表
- cassandra - 尝试将 Cassandra 中的压缩更新为 TimeWindow 策略,但失败并出现错误
- php - 找不到类 'TYPO3\CMS\Adminpanel\Utility\StateUtility'
- php - 未设置的问题(PHP)
- node.js - JavaScript xml2js 从 xml 文档中的每个对象读取数组
- pandas - 新列中的 Pandas groupby 和 agg 值