3
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 */

为什么?

输出(测试结果)

请参阅PasteBin

MDN 文档

  1. Element.getBoundingClientRect()
  2. DOMRect
4

1 回答 1

5

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

您可以通过以下方式证明:

let rect = el.getBoundingClientRect();
rect.hasOwnProperty('x');                        // === false
Object.getPrototypeOf(rect).hasOwnProperty('x'); // === true

我使用 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! */

(虽然它只迭代了一层继承,但仍然会丢失更深层次的属性)

于 2017-03-10T08:57:38.950 回答