В большинстве ответов используется какая-то утка, например, проверяется, есть ли у объекта свойство nodeType
. Но этого недостаточно, поскольку неузлы также могут иметь свойства, подобные узлам.
Другим распространенным подходом является instanceof
, который может давать ложные срабатывания, например, с Object.create(Node)
, который не является узлом, несмотря на наследование свойств узла.
Кроме того, оба вышеупомянутых подхода вызывают внутренние существенные методы, которые могут быть проблематичными, например, если проверенное значение является прокси.
Вместо этого я рекомендую заимствовать метод узла и вызывать его для нашего объекта. Браузер проверит, что значение является узлом, вероятно, посмотрев внутренние слоты, не настраиваемые в прокси, поэтому даже они не смогут помешать нашей проверке.
function isNode(value) {
try {
Node.prototype.cloneNode.call(value, false);
return true;
} catch(err) {
return false;
}
}
Вы также можете использовать свойства getter, если хотите.
function isNode(value) {
try {
Object.getOwnPropertyDescriptor(Node.prototype,'nodeType').get.call(value);
return true;
} catch(err) {
return false;
}
}
Аналогично, если вы хотите проверить, является ли значение элементом, вы можете использовать
function isElement(value) {
try {
Element.prototype.getAttribute.call(value, '');
return true;
} catch(err) {
return false;
}
}
function isHTMLElement(value) {
try {
HTMLElement.prototype.click.call(value);
return true;
} catch(err) {
return false;
}
}