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

Why check for element/attributes before removing it?

本文关键字:检查 属性 删除 元素 为什么      更新时间:2023-09-26

在《学习Javascript -现代Javascript基础实践指南》中的使用属性节点一章中,作者Tim Wright在第73页说:

删除属性和获取属性一样简单。我们只是针对元素节点,并使用removeAttribute()方法将其从那里取出。如果试图删除不存在的属性,则不会抛出Javascript异常,但是最好还是使用我们前面提到的hasAttribute()方法,如清单4.6.4

所示。

清单4.6.4用于删除图像Class值的Javascript

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

如果两种方式都没有抛出异常,检查它是否存在不是多余的吗?同样的结果也会出现。书中所说的论点是,在删除参数之前检查参数,可以通过不必要的代码节省浏览器解析,但if(document.getElementById("pic").hasAttribute("class")) {}甚至比document.getElementById("pic").removeAttribute("class");本身更长!

为什么是最佳实践?

在我看来你的假设是完全正确的。我认为书中的"建议"是灾难性的(用一个戏剧性的术语来说)。以前在任何地方都没有听说过这种"最佳实践"。在删除/更改属性之前使用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 -好的部分, by Douglas Crockford
JavaScript Ninja的秘密,作者:John Resig (jQuery背后的家伙)

买书!它们是金色的,作为你桌上的参考。

我想到的一件事是,removeAttribute可能是一个更重的函数调用关于它所做的操作,即,它修改DOM和HTML,也可能影响浏览器中的元数据。

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

如果removeAttribute本身已经做了hasAttribute检查,那么我同意它是相当多余的。

在编写大型程序或在团队中工作时非常有用....你需要检查你没有删除正在被其他人使用的东西。如果有一个更技术性的答案,希望别人会提供它。