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

发布于 2024-08-21 21:24:51 字数 468 浏览 5 评论 0原文

给出以下代码:

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"] 这样的数组。

这可能吗?我相信我已经在某处看到了一个答案,它描述了如何找出这个问题,但我一生都无法再次找到它。

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. 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? How can we discover the members of its prototype chain? Ideally I'd like an array like [b, a, Object] or ["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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空名 2024-08-28 21:24:51

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

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

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

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

Well, the prototype link between objects ([[Prototype]]) is internal, some implementations, like the Mozilla, expose it as 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.

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__:

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.

葬花如无物 2024-08-28 21:24:51

编辑 - 这个答案是 2010 年的,而且已经过时了。从那时起,该语言添加了 Object.getPrototypeOf() API,这极大地简化了该过程。


您可以使用对象的“构造函数”属性来查找那里的原型,然后沿着它链接,直到到达彩虹的尽头。

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。

edit — This answer is from 2010, and quite obsolete. Since then the language has added the Object.getPrototypeOf() API, which vastly simplifies the process.


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.

杀手六號 2024-08-28 21:24:51

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

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

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;
}
看春风乍起 2024-08-28 21:24:51

这是一个没有递归函数调用的简单方法

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

这是一个使用此函数的示例

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

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

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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文