检查tagName还是instanceof HTMLAnchorElement是否更好

问题描述 投票:0回答:2

如果我想检查特定的 DOM 节点是否是锚元素,哪个选项会更安全、更快?

通过更安全,我正在寻找较旧的浏览器(例如 IE6-8)更好地支持哪个。

我假设速度不会有太大差异,但如果一个函数在遍历 DOM 树时执行此检查,可能会节省几毫秒。

javascript dom
2个回答
0
投票

兼容性

tagName
instanceof
在我出生之前就得到了支持。

性能

使用

tagName
instanceof
稍快,因为它不需要检查原型链。

请参阅此处的基准测试。

类型检查

如果您使用像 TypeScript 这样的类型检查器, 有时使用

instanceof
更好,因为您可以利用 类型缩小

例如:

    document.addEventListener('click', (e) => {
        if (e.defaultPrevented) return;
        const target = e.target; // Here the type is EventTarget, and target.href is not a known member.
        if (
            target instanceof HTMLAnchorElement &&
            target.href && // Here the type is HTMLAnchorElement, avoiding a type error.
            target.target === '_blank'
        ) {
            // The type is narrowed to HTMLAnchorElement inside the condition body as well.
            e.preventDefault();
            discordSdk.commands.openExternalLink({ url: target.href });
        }
    });

如果使用

tagName
,类型检查器会抱怨未知属性
href
target

此外,使用

tagName
,更容易犯错误,例如忘记将标签名称大写或拼写错误, 而使用类的名称,类型检查器可以验证它是否存在。

跨页面上下文

如果您使用

iframe
元素,并通过
contentWindow
contentDocument
访问其中的元素,
instanceof
可能无法按预期工作,因为每个框架都有自己的 DOM 对象类版本,例如
HTMLAnchorElement

尝试在任何页面的控制台中运行此代码:

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentDocument.write('<a href="https://example.com" target="_blank">Click me</a>');
iframe.contentDocument.close();
const anchor = iframe.contentDocument.querySelector('a');

console.log("A)", anchor.tagName === 'A'); // true
console.log("B)", anchor instanceof HTMLAnchorElement); // false
console.log("C)", anchor instanceof iframe.contentWindow.HTMLAnchorElement); // true

在这种情况下,使用

instanceof
的正确代码是使用
tagName
的两倍多。

更多示例:

iframe.contentWindow.isItAnAnchor1 = (el) => el instanceof HTMLAnchorElement;
iframe.contentWindow.isItAnAnchor2 = function(el) { return el instanceof HTMLAnchorElement; };
iframe.contentWindow.isItAnAnchor3 = function(el) { return el instanceof self.HTMLAnchorElement; };
iframe.contentWindow.isItAnAnchor4 = (el)=> el instanceof this.HTMLAnchorElement;
iframe.contentWindow.isItAnAnchor5 = function(el) { return el instanceof this.HTMLAnchorElement; };
console.log("D)", iframe.contentWindow.isItAnAnchor1(anchor)); // false, because `HTMLAnchorElement` refers to the parent window's version
console.log("E)", iframe.contentWindow.isItAnAnchor2(anchor)); // false, because `HTMLAnchorElement` refers to the parent window's version
console.log("F)", iframe.contentWindow.isItAnAnchor3(anchor)); // false, because `self` refers to the parent window
console.log("G)", iframe.contentWindow.isItAnAnchor4(anchor)); // false, because `this` refers to the parent window
console.log("H)", iframe.contentWindow.isItAnAnchor5(anchor)); // true, because `this` refers to the iframe's window in this case

-1
投票

使用 javascript,99% 的情况下 proc 资源都不是优先考虑的。 如果您必须检查 tagName,您最好使用显式暴露给您的 tagName。

对我来说,instanceof要长得多,因为你必须检查原型的类型,tagName是一个已经设置的属性。

© www.soinside.com 2019 - 2024. All rights reserved.