getBoundingClientRect()无法复制对象属性

7vu*_*0hy 3 javascript getboundingclientrect

function test(o) {
    console.log("Object:", o);
    console.log("Assign test:", Object.assign({}, o));
    console.log("Keys test:", Object.keys(o));
    console.log("JSON test:", JSON.stringify(o));
}

var el = document.getElementById("question");                 /* or document.body */

test(el.style);                                               /* works as expected */
test(el.getBoundingClientRect());                             /* behaves like {} */
test(Object.assign(el.getBoundingClientRect(),{aaaa: 1111})); /* works... only for aaaa */
Run Code Online (Sandbox Code Playgroud)

为什么?

输出(测试结果)

参见PasteBin

MDN文档

  1. Element.getBoundingClientRect()
  2. DOMRect

pht*_*hts 5

Object.assign并且Object.keys正在使用自己的可枚举属性。DOMRect属性是从DOMRectPrototype那些方法继承的,并且不能被这些方法访问。

您可以通过以下方式证明这一点:

let rect = el.getBoundingClientRect();
rect.hasOwnProperty('x');                        // === false
Object.getPrototypeOf(rect).hasOwnProperty('x'); // === true
Run Code Online (Sandbox Code Playgroud)

我使用了Lodash _.assignIn来迭代自己和继承的源属性:

https://jsfiddle.net/msazmfxo/

更新

根据此答案,7vujy0f0hy找到了可接受的解决方案

var ownify = input => 
               Object.keys(Object.getPrototypeOf(input)).reduce((output,key) => 
                 Object.assign(output, {[key]: input[key]}), Object.assign({}, input));

test(ownify(el.getBoundingClientRect())); /* apparently works! */
Run Code Online (Sandbox Code Playgroud)

(尽管仅迭代一个继承级别,但仍将缺少更深层次的属性)