我想要:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
在我自己的脚本中,我曾经只使用这个,因为我从来不需要tagName作为属性:
if (!object.tagName) throw ...;
所以对于第二个目标,我想出了下面的快速解决方案——这基本上是有效的。;)
问题是,它依赖于浏览器强制执行只读属性,而并非所有浏览器都这样做。
function isDOM(obj) {
var tag = obj.tagName;
try {
obj.tagName = ''; // Read-only for DOM, should throw exception
obj.tagName = tag; // Restore for normal objects
return false;
} catch (e) {
return true;
}
}
有好的替代品吗?
也许这是另一种选择?在Opera 11, FireFox 6, Internet Explorer 8, Safari 5和谷歌Chrome 16中测试。
function isDOMNode(v) {
if ( v===null ) return false;
if ( typeof v!=='object' ) return false;
if ( !('nodeName' in v) ) return false;
var nn = v.nodeName;
try {
// DOM node property nodeName is readonly.
// Most browsers throws an error...
v.nodeName = 'is readonly?';
} catch (e) {
// ... indicating v is a DOM node ...
return true;
}
// ...but others silently ignore the attempt to set the nodeName.
if ( v.nodeName===nn ) return true;
// Property nodeName set (and reset) - v is not a DOM node.
v.nodeName = nn;
return false;
}
函数不会被例如这个所欺骗
isDOMNode( {'nodeName':'fake'} ); // returns false
var IsPlainObject = function ( obj ) { return obj instanceof Object && ! ( obj instanceof Function || obj.toString( ) !== '[object Object]' || obj.constructor.name !== 'Object' ); },
IsDOMObject = function ( obj ) { return obj instanceof EventTarget; },
IsDOMElement = function ( obj ) { return obj instanceof Node; },
IsListObject = function ( obj ) { return obj instanceof Array || obj instanceof NodeList; },
//事实上我更倾向于内联使用这些快捷方式,但有时为设置代码提供这些快捷方式是很好的