在《学习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检查,那么我同意它是相当多余的。
在编写大型程序或在团队中工作时非常有用....你需要检查你没有删除正在被其他人使用的东西。如果有一个更技术性的答案,希望别人会提供它。