给出以下代码:
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上找到了一个答案,描述了如何找到这个,但我不能为我的生活找到它。
答案 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;
}