getAllMethodNames函数返回实例原型链上所有自有且为函数的属性名数组,从obj.__proto__开始遍历至Object.prototype,使用Object.getOwnPropertyNames获取属性并筛选typeof为'function'者。

要遍历 JavaScript 原型链并获取所有可调用的方法(即函数属性),核心是沿着 __proto__(或更推荐的 Object.getPrototypeOf())向上走,逐级检查每个原型对象上的自有属性,筛选出类型为 "function" 的属性名。
只获取“方法名”(字符串数组)
以下函数返回从实例开始、沿原型链向上所有可枚举且为函数的属性名(不含内置如 constructor、toString 等,除非你显式定义过):
function getAllMethodNames(obj) {
const methods = new Set();
let current = obj;
<p>while (current && current !== Object.prototype) {
const proto = Object.getPrototypeOf(current);
if (!proto) break;</p><pre class="brush:php;toolbar:false;">Object.getOwnPropertyNames(proto).forEach(key => {
const desc = Object.getOwnPropertyDescriptor(proto, key);
// 只收集自有、可枚举(或不关心枚举性时可去掉 hasOwnProperty 判断)、且值为函数的属性
if (desc && typeof proto[key] === 'function') {
methods.add(key);
}
});
current = proto;}
return Array.from(methods); }
⚠️ 注意:
- Object.getOwnPropertyNames() 获取包括不可枚举属性(如 hasOwnProperty),但实际中多数自定义方法是可枚举的;
- 如果你只想获取可枚举方法,改用 Object.keys(proto);
- constructor 会被包含(它是函数),如需过滤可加 key !== 'constructor' 条件。
获取“方法名 + 所在原型”映射(便于调试)
有时需要知道某个方法定义在哪一级原型上,可用对象记录来源:
function getAllMethods(obj) {
const result = {};
let current = obj;
<p>while (current && current !== Object.prototype) {
const proto = Object.getPrototypeOf(current);
if (!proto) break;</p><pre class="brush:php;toolbar:false;">Object.getOwnPropertyNames(proto).forEach(key => {
if (typeof proto[key] === 'function') {
if (!(key in result)) {
result[key] = proto; // 首次出现的位置(最接近实例的一层)
}
}
});
current = proto;}
return result; }
// 使用示例: // const arr = []; // console.log(getAllMethods(arr)); // { push: Array, map: Array, filter: Array, ... }
排除内置方法,只取自定义方法
若想跳过 Object.prototype 和 Array.prototype 等原生方法,只保留你自己添加的(比如通过 MyClass.prototype.xxx = function(){} 定义的),关键是识别「自定义原型」:
- 提前保存你定义的构造函数原型,比如
const myProto = MyClass.prototype; - 遍历时只检查
current === myProto或其子类原型(需配合instanceof或构造器判断); - 更简单方式:给自定义原型加个标记,如
MyClass.prototype.__custom = true,然后在循环中加if (proto.__custom)过滤。
注意事项与边界情况
-
obj本身的方法(实例方法)不会被包含——上面代码从obj.__proto__开始,如需包含实例自身函数属性,先用Object.getOwnPropertyNames(obj)检查一遍; - 箭头函数不会出现在原型上,它不是“方法”,只是普通属性值;
- ES6 class 中定义的
method() {}是不可枚举的,但仍在getOwnPropertyNames()结果中; - 避免无限循环:确保终止条件覆盖
null(如Object.create(null)的原型链终点)和Object.prototype; - 不建议用
__proto__属性遍历,应始终使用Object.getPrototypeOf()。


















