如何查找满足foo.prototype instanceof bar的对象及构造函数列表?
一、查找所有满足foo.prototype instanceof bar的对象
首先得明确这个条件的含义:bar的原型出现在foo.prototype的原型链上,换句话说,foo的原型对象继承自bar的实例(或者说foo是bar的间接子类构造函数)。
要找到所有符合条件的foo,我们可以遍历全局环境中的所有属性,筛选出满足条件的构造函数。这里给出一个实用的实现函数:
function findObjectsWherePrototypeInstanceOf(bar) { const result = []; // 适配浏览器和Node.js环境的全局对象 const globalScope = typeof window !== 'undefined' ? window : global; // 遍历全局对象的所有自有属性(包括不可枚举的) for (const key of Object.getOwnPropertyNames(globalScope)) { const candidate = globalScope[key]; // 只考虑带有prototype属性的函数(构造函数通常是函数类型) if (typeof candidate === 'function' && candidate.prototype) { try { // 检查prototype是否在bar的原型链上 if (candidate.prototype instanceof bar) { result.push(candidate); } } catch (err) { // 部分特殊内置对象访问prototype会抛出异常,直接跳过 continue; } } } return result; }
使用示例
比如要找所有原型继承自Object实例的构造函数,直接调用:
const objInheritors = findObjectsWherePrototypeInstanceOf(Object); console.log(objInheritors);
输出结果会包含Function、Array、Number、Boolean、String、Symbol、Date、Promise、RegExp、Error系列(EvalError、RangeError等)、各类ArrayBuffer和TypedArray等,和你期望的结果一致。
二、获取所有原型为某对象实例的构造函数列表
这个需求其实就是第一个问题的具体化——我们可以封装一个更语义化的inheritors函数,本质和上面的函数逻辑一致:
function inheritors(target) { return findObjectsWherePrototypeInstanceOf(target); }
使用示例
调用inheritors(Object)就能得到你想要的结果:
inheritors(Object) [Function, Array, Number, Boolean, String, Symbol, Date, Promise, RegExp, Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, ArrayBuffer, Uint8Array, Int8Array, Uint16Array, Int16Array, Uint32Array, Int32Array, Float32Array, Float64Array...]
注意事项
- 这个方法只能检测全局环境中的构造函数,局部作用域内定义的自定义构造函数如果没有挂载到全局,是无法被找到的。
- 不同运行环境(浏览器、Node.js、小程序等)的全局对象属性不同,返回结果会有差异,比如Node.js中会包含
Buffer、process相关构造函数,浏览器中会包含HTMLElement等DOM相关构造函数。 - 部分特殊内置对象(比如
Symbol)访问prototype可能抛出异常,函数里的try-catch会自动跳过这些情况。
内容的提问来源于stack exchange,提问作者Ben Rivers

