代码之家  ›  专栏  ›  技术社区  ›  Qian Chen

为什么是{…window}。数学没有定义?

  •  1
  • Qian Chen  · 技术社区  · 5 年前

    const a = {x:1};
    console.log({...a}.x);
    // 1
    
    console.log(window.Math);
    // Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    
    console.log({...window}.Math);
    // undefined

    我不明白为什么 {...a}.x 评估结果为1,但 {...window}.Math 计算结果为undefined。

    2 回复  |  直到 5 年前
        1
  •  2
  •   marc_s    5 年前

    那是因为 Math 无法枚举。

    这个 ECMA-2018 (ES9) specs 有点难读。 MDN 以及a proposal page 规定的: {...obj} 为所有对象创建一个新对象 obj 的(1)自己的 (2) 可枚举属性。 数学 window 的自己的属性,但不可枚举:

    console.log(window.hasOwnProperty("Math"));
    console.log(Object.getOwnPropertyDescriptor(window, "Math"));

    你可以用一个对象来重现这种情况:

    obj = {};
    
    Object.defineProperty(obj, 'x', {
      enumerable: false,
      value: 123
    });
    
    console.log(obj);   // Google Chrome prints { x: 123 } but StackOverflow prints {} and Node.js prints {} too
    console.log(obj.x);
    console.log(({...obj}).x);
        2
  •  1
  •   epinadev    5 年前

    {…Window}正在使用展开运算符将副本复制到新对象中。数学是不可枚举的,因此它不会被复制到新对象中。

    你可以自己测试一下:

    const a = {}
    Object.defineProperty(a, "prop1", { value: "enumerable", enumerable: true })
    Object.defineProperty(a, "prop2", { value: "not enumerable", enumerable: false })
    

    然后复制您的对象:

    {...a}.prop1 //"enumerable"
    {...a}.prop2 // undefined