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

时间:2010-02-11 05:41:01

标签: javascript prototype prototypal-inheritance

给出以下代码:

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

我们可以留下a添加到b的原型链中。大。并且,以下所有都是真的:

b1 instanceof b
b1 instanceof a
b1 instanceof Object

我的问题是,如果我们提前不知道b1的来源怎么办?我们怎样才能发现其原型链的成员?理想情况下,我想要一个像[b, a, Object]["b", "a", "Object"]这样的数组。

这可能吗?我相信我已经在SO上找到了一个答案,描述了如何找到这个,但我不能为我的生活找到它。

4 个答案:

答案 0 :(得分:7)

嗯,对象([[Prototype]])之间的原型链接是内部的,有些实现(如Mozilla)将其公开为obj.__proto__

ECMAScript第5版的Object.getPrototypeOf方法正是您所需要的,但目前尚未在大多数JavaScript引擎上实现。

看看John Resig的这个implementation,它有一个陷阱,它依赖于不支持constructor的引擎的__proto__属性:

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;
    };
  }
}

请记住,这不是100%可靠,因为constructor属性在任何对象上都是可变的。

答案 1 :(得分:2)

编辑 - 这个答案来自2010年,已经过时了。从那以后,该语言添加了Object.getPrototypeOf() API,大大简化了流程。


你可以使用对象的“constructor”属性在那里找到原型,然后沿着它链接,直到你到达彩虹的尽头。

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, []);
}

(也许)(或者可能不是:-)给我一个秒)(好的废话;我认为这是可能的,但忽略该代码)

[编辑]哇这完全是我的想法 - 这个功能很接近但不太正确;建立原型链是很奇怪的,我感到害怕和孤独。我建议只关注上面那个很棒的@CMS。

答案 2 :(得分:0)

这是一个起点:

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

当然这确实是不完整的,但我认为它在大多数情况下会有效,如果有人想添加它,他们可以。

答案 3 :(得分:0)

另一种获取原型链的方法:

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;
}