具有属性的对象不一定意味着该对象拥有"属性;它可以在原型链中.对此进行检查(在Chrome DevTools控制台中):Object.create({"foo":"bar"}).hasOwnProperty("foo")false"foo" in Object.create({"foo":"bar"})true如您所见,foo确实存在于所创建的对象中,但并不属于该对象,而是位于原型链中.当谈论DOM原型时,事情可能会有些复杂,因为不同的平台可能会以不同的方式实现同​​一件事.根据 MDN ,clientHeight是是在Element.prototype中定义的,所以在Firefox的控制台中,我得到了:[17:09:55.701] document.documentElement.hasOwnProperty("clientHeight")[17:09:55.702] false--[17:10:19.894] "clientHeight" in document.documentElement[17:10:19.895] true但是在Opera Dragonfly控制台中,我得到了:>>> document.documentElement.hasOwnProperty("clientHeight")true>>> "clientHeight" in document.documentElementtrue在Chrome DevTools控制台中,我得到了:document.documentElement.hasOwnProperty("clientHeight")true"clientHeight" in document.documentElementtrue(我现在没有要测试的IE10,但如果我没记错的话,IE10就是Firefox风格)因此在Chrome和Opera中,似乎clientHeight是按每个元素"定义的,而不是在Element.prototype中定义的.再往前走,您会看到:Object.getPrototypeOf(document.documentElement)HTMLHtmlElement {insertAdjacentHTML: function, insertAdjacentText: function, click: function, insertAdjacentElement: function, getAttribute: function…} constructor: function HTMLHtmlElement() { [native code] } __proto__: HTMLElement click: function click() { [native code] } constructor: function HTMLElement() { [native code] } insertAdjacentElement: function insertAdjacentElement() { [native code] } insertAdjacentHTML: function insertAdjacentHTML() { [native code] } insertAdjacentText: function insertAdjacentText() { [native code] } __proto__: Element对于您的问题,我想说的是,无论您要完成什么,都不要依赖此标准",而要使用功能检测.当我尝试在JS中克隆对象时,我首先注意到了这种行为.当尝试克隆ClientRect对象(例如document.body.getBoundingClientRect())时,当我想花一点点时间时,我首先尝试:var cloned={};if(cloned.__proto__) { cloned.__proto__=source.__proto__;}for(var i in source) { if(Object.prototype.hasOwnProperty.call(source,i)){ cloned[i]=source[i]; }}在Chrome中工作正常,但在Firefox中,cloned看起来像{width:undefined,height:undefined...}.因此,我将for..in更改为此:for(var in source) { cloned[i]=source[i];}在Firefox中,这在最初的i给了我一个例外,因为这6个属性是只读的.经过几次失败后,我得出结论,Firefox中的ClientRect是不可构造的,因此不能严格完全克隆.I try to check property clientHeight by this code:document.documentElement != null && document.documentElement.hasOwnProperty('clientHeight')and the result is false because of document.documentElement.hasOwnProperty('clientHeight')but when i check it by 'clientHeight' in document.documentElement it return true. In Chrome,FF,Opera all works fine. What is the reason for this behavior? 解决方案 Not answering your question (what is the reason for this), but still want to share, so extending from comment:An object with a property doesn't necessary mean that property is "owned" by that object; it can be in the prototype chain.Check about this (in Chrome DevTools console):Object.create({"foo":"bar"}).hasOwnProperty("foo")false"foo" in Object.create({"foo":"bar"})trueSo as you can see, foo does exist in the created object, but it's not "owned" by the object, just sits in the prototype chain.When talk about DOM prototype, things can be a little bit more complicated as different platform may implement the same thing differently.According to MDN, clientHeight is defined in Element.prototype, soin Firefox's console, I got:[17:09:55.701] document.documentElement.hasOwnProperty("clientHeight")[17:09:55.702] false--[17:10:19.894] "clientHeight" in document.documentElement[17:10:19.895] truebut in Opera Dragonfly console, I got:>>> document.documentElement.hasOwnProperty("clientHeight")true>>> "clientHeight" in document.documentElementtrueand in Chrome DevTools console, I got:document.documentElement.hasOwnProperty("clientHeight")true"clientHeight" in document.documentElementtrue(No IE10 for me to test right now, but if I remember correctly, IE10 follows Firefox style)So it seems in Chrome and Opera, clientHeight is defined "per element", not in Element.prototype. Go a little further and you can see:Object.getPrototypeOf(document.documentElement)HTMLHtmlElement {insertAdjacentHTML: function, insertAdjacentText: function, click: function, insertAdjacentElement: function, getAttribute: function…} constructor: function HTMLHtmlElement() { [native code] } __proto__: HTMLElement click: function click() { [native code] } constructor: function HTMLElement() { [native code] } insertAdjacentElement: function insertAdjacentElement() { [native code] } insertAdjacentHTML: function insertAdjacentHTML() { [native code] } insertAdjacentText: function insertAdjacentText() { [native code] } __proto__: ElementAs to your problem, I would say, whatever you're trying to accomplish, don't depend on this "standard", use feature detection.I first noticed this behavior when I tried to clone object in JS.When trying to clone a ClientRect object (e.g. document.body.getBoundingClientRect()), when I want to go a little bit fancy, I first tried:var cloned={};if(cloned.__proto__) { cloned.__proto__=source.__proto__;}for(var i in source) { if(Object.prototype.hasOwnProperty.call(source,i)){ cloned[i]=source[i]; }}In Chrome it works fine, but in Firefox the cloned looks like {width:undefined,height:undefined...}. So I changed the for..in to this:for(var in source) { cloned[i]=source[i];}In Firefox this gave me an Exception at the very first i because those 6 properties are read only.After some failure I concluded that ClientRect in Firefox is not constructible, so not strictly, perfectly cloneable. 这篇关于ie10中clientHeight的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
06-10 21:37