简体   繁体   English

如何查看 Javascript 对象的原型链?

[英]How can I see a Javascript object's prototype chain?

Given the following code:给定以下代码:

function a() {}
function b() {}
b.prototype = new a();
var b1 = new b();

We can stay that a has been added to b 's prototype chain.我们可以保留a已添加到b的原型链中。 Great.伟大的。 And, all the following are true:并且,以下所有内容都是正确的:

b1 instanceof b
b1 instanceof a
b1 instanceof Object

My question is, what if we don't know the origins of b1 ahead of time?我的问题是,如果我们不提前知道b1的起源怎么办? How can we discover the members of its prototype chain?我们如何发现其原型链的成员? Ideally I'd like an array like [b, a, Object] or ["b", "a", "Object"] .理想情况下,我想要一个像[b, a, Object]["b", "a", "Object"]这样的数组。

Is this possible?这可能吗? I believe I've seen an answer somewhere on SO that described how to find out just this but I can't for the life of me find it again.我相信我已经在 SO 的某个地方看到了一个答案,该答案描述了如何找出这一点,但我终生无法再次找到它。

Well, the prototype link between objects ( [[Prototype]] ) is internal, some implementations, like the Mozilla, expose it as obj.__proto__ .好吧,对象之间的原型链接( [[Prototype]] )是内部的,一些实现,如 Mozilla,将其公开为obj.__proto__

The Object.getPrototypeOf method of the ECMAScript 5th Edition is what you're needing, but it isn't implemented right now on most JavaScript engines. ECMAScript 第 5 版的Object.getPrototypeOf方法是您所需要的,但现在大多数 JavaScript 引擎都没有实现它。

Give a look to this implementation by John Resig, it has a pitfall, it relies on the constructor property of engines that don't support __proto__ :看看 John Resig 的这个实现,它有一个陷阱,它依赖于不支持__proto__的引擎的constructor属性:

if ( typeof Object.getPrototypeOf !== "function" ) {
  if ( typeof "test".__proto__ === "object" ) {
    Object.getPrototypeOf = function(object){
      return object.__proto__;
    };
  } else {
    Object.getPrototypeOf = function(object){
      // May break if the constructor has been tampered with
      return object.constructor.prototype;
    };
  }
}

Remember that this is not 100% reliable, since the constructor property is mutable on any object.请记住,这不是 100% 可靠的,因为constructor属性在任何对象上都是可变的。

edit — This answer is from 2010, and quite obsolete.编辑——这个答案来自 2010 年,已经过时了。 Since then the language has added the Object.getPrototypeOf() API, which vastly simplifies the process.从那时起,该语言添加了Object.getPrototypeOf() API,极大地简化了流程。


You could use the "constructor" property of the object to find the prototype there, and then chain along that until you reached the end of the rainbow.您可以使用对象的“构造函数”属性在那里找到原型,然后沿着它链接直到到达彩虹的尽头。

function getPrototypes(o) {
  return (function gp(o, protos) {
    var c = o.constructor;
    if (c.prototype) {
      protos.push(c.prototype);
      return gp(c.prototype, protos);
    }
    return protos;
  })(o, []);
}

(maybe) (or maybe not :-) give me a sec) (well crap; I think it's possible but ignore that code) (也许)(或者也许不是:-)给我一秒钟)(废话;我认为这是可能的,但忽略该代码)

[edit] wow this is totally blowing my mind - that function's close but not quite right; [编辑] 哇,这让我大吃一惊——这个功能很接近但不太正确; setting up a chain of prototypes is weird and I'm feeling scared and lonely.建立一系列原型很奇怪,我感到害怕和孤独。 I suggest paying attention only to the awesome @CMS above.我建议只关注上面很棒的@CMS。

Here is a starting point: 这是一个起点:

Object.prototype.getConstructorNames=function(){
        return Object.keys(window).filter(function(e){
            return typeof window[e]==="function" && this instanceof window[e]},this)
    }

Of course this is really incomplete but I think it will work in most cases and if anyone wants to add to it they can. 当然这实际上是不完整的,但我认为它在大多数情况下会起作用,如果有人想添加它,他们可以。

Another way to get the prototype chain:另一种获取原型链的方法:

function getPrototypeChain(obj) {
  let prototypeChain = [];
  (function innerRecursiveFunction(obj) {
    let currentPrototype = (obj != null) ? Object.getPrototypeOf(obj) : null;
    prototypeChain.push(currentPrototype);
    if (currentPrototype != null) {
      innerRecursiveFunction(currentPrototype);
    }
  })(obj);
  return prototypeChain;
}

Here is a simple method without recursive function calls这是一个没有递归函数调用的简单方法

function getProtoChain(o) {
    const ans = []
    let t = o
    while (t) {
        t = t.__proto__
        ans.push(t)
    }
    return ans
}

Here is an example use of this function这是此功能的示例使用

class A {}
class B extends A {}
class C extends B {}

console.log(getProtoChain(new C())) // [C: {}, B: {}, A: {}, {}, null]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript:如何获取对象的原型链构造函数名称列表? - Javascript: How to get a list of an object's prototype chain constructor names? 如何使用给定的原型链创建对象? - How can I create an object with a given prototype chain? JavaScript 原型链参考 Object.prototype - JavaScript Prototype Chain Reference to Object.prototype 为什么在该对象的原型链中还有一个额外的原型? - Why is there an extra prototype in this object's prototype chain? JavaScript对象可以有一个原型链,但也可以是一个函数? - Can a JavaScript object have a prototype chain, but also be a function? 为什么当我在此JavaScript对象上使用反射时,看不到其原型对象中定义的属性? - Why when I use reflection on this JavaScript object I can't see a property defined in its prototype object? 如何在不调用构造函数的情况下复制对象及其原型链? - How do I copy an object and it's prototype chain without calling its constructor function? 如何使用声明中的变量使用Javascript的原型扩展对象? - How can I extend an object with Javascript's prototype using variables in the declaration? Javascript:如何复制对象并保持其原型链? - Javascript: how to copy a object and keep its prototype chain? 如何遍历对象原型链中的所有属性? - How to iterate over all properties in object's prototype chain?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM