代码之家  ›  专栏  ›  技术社区  ›  Ood

JavaScript:使用原型链进行对象透视

  •  0
  • Ood  · 技术社区  · 1 年前

    浏览器控制台允许您使用树状结构检查对象,例如:

    console.log(document);
    

    然后我可以自由浏览对象,包括它的原型和原型的原型等等。我想复制这种行为,但在实现“原型的原型”功能时遇到了问题。

    我的代码可以很好地在原型中获取密钥,但在尝试记录它们时会抛出一个错误。(我正在使用 var 以便更容易在控制台中重复测试。)

    以下是演示该问题的简化版本:

    var prototype = Object.getPrototypeOf(document);
    var prototypeOfPrototype = Object.getPrototypeOf(prototype);
    
    // This works, so the values are there
    
    var keys = Object.getOwnPropertyNames(prototypeOfPrototype);
    
    console.log(keys);
    
    var values = keys.map((key) => {
        
        // This throws an error although it shouldn't be executing anything here
                                    
        console.log(prototypeOfPrototype[key]);
    
    });
    

    我得到的错误如下:

    铬:

    "Illegal invocation"
    

    火狐浏览器:

    "Uncaught TypeError: 'get implementation' called on an object that does not implement interface Document."
    

    至少对我来说,这些并没有真正的帮助。如果有人知道为什么会发生这种情况,或者我如何在避免错误的同时实现此功能,我们将不胜感激。

    1 回复  |  直到 1 年前
        1
  •  2
  •   Bergi    1 年前

    当您在一个不应该访问的对象上访问getter时,就会发生这种情况,在本例中是原型,而不是 document (实际情况)。因此,我建议使用 Object.getOwnPropertyDescriptors 而不是 Object.getOwnPropertyNames 以下为:

    var prototype = Object.getPrototypeOf(document);
    var prototypeOfPrototype = Object.getPrototypeOf(prototype);
    var properties = Object.getOwnPropertyDescriptors(prototypeOfPrototype);
    
    for (const [key, descriptor] of Object.entries(properties)) {
        const value = "value" in descriptor ? descriptor.value : descriptor.get.call(document);
        console.log(key, typeof value);
    }