为什么在删除元素/属性之前要检查它?

7
学习Javascript - 现代Javascript基础入门实践指南使用属性节点章节中,作者Tim Wright在第73页上说:

移除属性和获取属性一样简单。我们只需针对元素节点并使用removeAttribute()方法将其移除即可。如果您尝试删除不存在的属性,则不会抛出Javascript异常,但最好仍然使用我们之前提到的hasAttribute()方法,如列表4.6.4所示。

清单4.6.4用于移除图像类值的Javascript代码

if(document.getElementById("pic").hasAttribute("class")) {
    document.getElementById("pic").removeAttribute("class");
}

如果两种情况都没有抛出异常,那么检查它是否存在是不是多余的呢?结果是相同的。书中提到的参数检查是为了避免浏览器解析不必要的代码,但是if(document.getElementById("pic").hasAttribute("class")) {}甚至比document.getElementById("pic").removeAttribute("class");本身还要长!那么这为什么是最佳实践呢?

我进行了一项性能测试这里,正如你所说,removeAttribute方法比hasAttribute检查更快。因此,请在这里为您的问题投票。 - fuyi
谢谢!有一件事...我不知道jsperf.com! - dayuloli
3
有一种更快的检查方式,即点表示法:http://jsperf.com/checkattributeornot。hasAttribute和removeAttribute都很慢。 - epascarello
哇...今天我学到了很多东西!点符号表示法和其他一切!:D 所以@epascarello你是说点符号表示法是最佳实践,而不是“检查方法”或仅仅删除它?最佳实践是否仅取决于每秒操作次数?那Weiwei所说的关于元数据和更重的函数调用呢? - dayuloli
1
我并不是说这是“最佳”实践。这只是为了速度而提供的一种选择。最佳实践是某个有意见的人认为你应该做的事情。 - epascarello
显示剩余3条评论
3个回答

3
在我看来,你的假设完全正确。我认为该书中的“建议”有点灾难性(使用一个戏剧性的术语)。我之前从没有听说过那种“最佳实践”。在删除/更改属性之前使用element.hasAttribute绝对不会带来任何好处,只会减慢代码运行速度。浏览器并没有神奇地拥有用于检查属性存在性的查找列表,而这个列表在设置或获取属性时不会被使用。尽管如此,在作者看来,这可能是一种最佳实践,适用于生成易读和易懂的代码。
此外,我认为你根本不应该使用setAttribute!只有在没有内置标准方法可以获取或设置某个属性时才使用setAttribute。这里所涉及到的是class
element.className = 'myclass';

替代

element.setAttribute('class', 'myclass');

浏览器在使用这种标准化方法时会进行优化处理。如果在为元素分配或删除属性时未使用,则浏览器必须确定其是何种类型的属性,然后可能会触发特殊操作 - 不一定每次都需要。

您可以像这样检查浏览器是否支持特定的属性方法

if (typeof window.document.body.className === 'string') {
   //className is supported for node elements
}

大多数属性方法都像 getter 和 setter 一样。您可以读取和写入它们,其中一些方法的使用甚至比其他方法更有效。例如:

element.outerHTML = '';

清理的内存比

element = null;

这当然不是针对元素的属性,而是展示为什么应该优先使用针对特定部分的内置方法。

有许多标准方法,例如element.className,你可以用它们来针对特定的标准属性进行操作。它们大多以驼峰表示法命名为属性名称。只有在需要创建自定义属性时才使用setAttribute。例如:

element.setAttribute('data-my-custum-attribute', 'hello');

根据HTML5标准,这是完全合法的标记。或者作为备用方案,如果浏览器不支持某个属性方法,可以使用它。对于非常老的浏览器可能会出现这种情况。但是即使IE6也支持className。
我将推荐两本我认为非常有价值的书籍,可以深入了解JavaScript(并不是说我完全掌握了它,但这些书帮助了我很多): Javascript - the good parts,作者是Douglas Crockford
Secrets of the JavaScript Ninja,作者是John Resig(jQuery背后的人)
买这些书!它们是您桌子上的黄金参考资料。

1
它们在JS中被简单地称为“属性”,或者在IDL中被称为“反射属性”,而不是“属性方法”。 - Bergi
1
IDL是一种交互式数据语言,用于科学、工程和商业应用程序的开发。它具有强大的数据处理和可视化功能,并支持多种操作系统。IDL还可以与其他编程语言(如C、Fortran和Python)集成使用。 - djvg

0

我心里想的一件事是,removeAttribute 可能是一个非常重的函数调用,因为它涉及到的操作很多,比如修改 DOM 和 HTML,还可能影响浏览器中的元数据。

相比之下,hasAttribute 只是一个读取操作,轻便得多,不会对元数据产生影响。所以最好检查元素是否具有该属性。

如果 removeAttribute 本身已经进行了 hasAttribute 检查,那么我同意这是非常冗余的。


1
这应该是一个注释。 - Romain Braun

-2

当你编写大型程序或在团队中工作时,这很有用...你需要检查你不要删除正在被其他东西/其他人使用的内容。如果有更技术性的答案,希望其他人能提供。


1
谢谢您的回复...但无论如何,元素/属性都将被删除。所有额外的代码只是在删除之前检查它是否存在。 - dayuloli
是的,这就是为什么检查一下会成为“最佳实践”,而不是使用remove函数的技术要求。最佳实践由epascarello在您的问题评论中定义:)。你可以自行决定是否想要使用最佳实践。 - user3037493

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接