Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么Chrome和Firefox在这里有区别?_Javascript_Firefox_Google Chrome_Clone_Hasownproperty - Fatal编程技术网

Javascript 为什么Chrome和Firefox在这里有区别?

Javascript 为什么Chrome和Firefox在这里有区别?,javascript,firefox,google-chrome,clone,hasownproperty,Javascript,Firefox,Google Chrome,Clone,Hasownproperty,我正在使用一个基于(..in..)和hasOwnProperty的递归函数来克隆对象,它在IE和FF中运行良好。。。但不是铬 当使用for(…in…)对对象的成员进行迭代时,如果对象是DOM对象,Firefox和Chrome会为hasOwnProperty提供不同的结果 在Chrome控制台和Firebug(FF)中的控制台中键入以下内容会得到不同的结果: var t = document.createElement("table"); var tr = t.insertRow(-1); for

我正在使用一个基于(..in..)和hasOwnProperty的递归函数来克隆对象,它在IE和FF中运行良好。。。但不是铬

当使用for(…in…)对对象的成员进行迭代时,如果对象是DOM对象,Firefox和Chrome会为hasOwnProperty提供不同的结果

在Chrome控制台和Firebug(FF)中的控制台中键入以下内容会得到不同的结果:

var t = document.createElement("table");
var tr = t.insertRow(-1);
for(var p in tr) if(tr.hasOwnProperty(p)) console.log(p);
Firefox输出:

构造函数
加法器

Chrome输出:

clientLeft
滚动高度
firstElementChild
offsetParent
ch
偏移网络宽度
不可编辑的内容
隐藏的
以前的元素同级
父元素
localName
儿童
所有者文档
节点值
lastElementChild
行索引
offsetLeft
标记名
类名
前缀
innerHTML
以前的兄弟姐妹
名称空间URI
id
childElementCount
innerText
向左滚动
阴蒂重量
对齐
文本内容
下一个签名
滚动宽度
远视
乔夫
客户端宽度
节点名称
风格

滚动顶部
偏置
子节点
baseURI
下一个入口同级
有效
sectionRowIndex
类列表
标题
第一个孩子
属性
数据集
outerText
细胞
父节点
clientTop
tabIndex
内容可编辑
外层TML
目录
最后一个孩子
bgColor
节点类型
拼写检查
拖拉的


对于hasOwnProeperty,所有标记为true的额外属性都会导致代码中出现“无限/足以崩溃”的重复现象。有没有办法确定proeperty是否是内置的DOM对象属性?或者其他的解决办法

最简单的解决方法是检查方法,如果存在,则使用该方法

这意味着您的克隆方法将检查任何DOM节点,并在其上使用预定义的DOM方法。这应该完全避免您的问题

至于你的实际问题。Chrome和Firefox似乎在HTMLTableRowElement(以及任何其他元素)的原型和对象上存在分歧

比较firefox和chrome中的console.dir(HTMLTableRowElement)

在firefox中,所有这些属性都位于
HTMLTableRowElement
原型上。其中,作为chrome原型,它只有几个方法。(
deletecell
insertCell

在DOM规范中,没有任何地方说明HTMLElements的属性应该在原型上定义,还是在对象上定义,所以这只是您不应该依赖的东西

无论哪种方法,都要使用
.cloneNode
,因为它是一种本机方法,因此比任何可以用JavaScript编写的方法都要好/更快

Chrome psuedo实现:

function HTMLTableRowElement() {
    ...
    this.nextSibling = ...;
    this.nodeName = ...;
    this.nodeType = ...;
    ...
}

HTMLTableRowElement.prototype.deleteCell = function() { ... };
HTMLTableRowElement.prototype.insertCell = function() { ... };
Firefox伪实现

function HTMLTableRowElement() {
    ...
}

HTMLTableRowElement.prototype.nextSibling = ...;
HTMLTableRowElement.prototype.nodeName = ...;
HTMLTableRowElement.prototype.nodeType = ...;
...
HTMLTableRowElement.prototype.deleteCell = function() { ... };
HTMLTableRowElement.prototype.insertCell = function() { ... };

我认为@Raynos在他的回答中提供了一个很好的解决方案。至于为什么事情会如此不同,我怀疑基本问题是DOM元素不是JavaScript对象——也就是说,它不会以任何方式从JavaScript“object”类继承。DOM元素由运行时提供,其行为和语义(通常)对JavaScript代码有意义,但它们在内部并不是真正的JavaScript对象。因此,对我来说,可以调用“hasOwnProperty”有点令人惊讶。

确定对象是否为DOM对象的最简单方法是检查该对象是否具有
节点名
节点值
节点类型
属性

if ( tr.nodeType > 0 ) {
    // tr is a DOM object
} else {
    // tr is not a DOM object
}

所有DOM对象都实现了,因此包含上述属性。

+1似乎很有趣。。JS大师-有什么指导吗?@Pointy我不同意。它们是JavaScript对象。它们确实从Object继承,并且从
HTMLTableRowElement
@Raynos继承。我不确定这是真的。它们周围可能有JavaScript对象包装器,我想浏览器实现中的一些JavaScript实际上可能会以这种方式实现它们,但我认为没有必要这样做。当然,在其他JavaScript环境中,运行时推入全局命名空间的“对象”不是JavaScript对象,即使它们可以从JavaScript代码访问。@Pointy Afaik,所有浏览器对象都继承自JavaScript的
对象。prototype
。如果有什么不同,我会感到惊讶。例如,
document
对象的原型链是:
document
-->
HTMLDocument.prototype
-->
document.prototype
-->
节点.prototype
-->
对象.prototype
-->
null
@Pointy true。它们不仅仅是JavaScript对象。我认为存在一个JavaScript对象的超集,但仍然存在与其他对象一样的对象。例如,你不能直接调用他们原型的构造函数,他们会做其他有趣的事情。@SimeVidas我喜欢“所有当前浏览器”这个短语,我现在可以假装IE8已经不存在了。放弃IE8支持会很好。@CAF我相信我的方法已经足够好了。。。这肯定是最简单的一个。这个问题的主要答案是杀得过火。
if ( tr.nodeType > 0 ) {
    // tr is a DOM object
} else {
    // tr is not a DOM object
}