要获取javascript对象原型链上的所有方法,必须沿原型链逐层遍历,使用object.getownpropertynames和object.getownpropertysymbols获取每层的自有属性(包括不可枚举的),再通过object.getownpropertydescriptor筛选出值为函数且非constructor的属性,最终去重返回;1. 使用while循环通过object.getprototypeof向上遍历直到null;2. 每层调用object.getownpropertynames和object.getownpropertysymbols获取所有字符串和symbol键名;3. 遍历所有键名,用object.getownpropertydescriptor判断属性值是否为函数并排除constructor;4. 使用try...catch避免因宿主对象或proxy导致的异常;5. 利用set去重后转为数组返回。该方法能完整获取原型链上所有方法,解决了for...in无法访问不可枚举属性、无法区分自有与继承属性等问题,适用于绝大多数标准与非标准场景。

要获取JavaScript对象原型链上的所有方法,核心思路是沿着原型链向上遍历,在每一层原型对象上,分别找出其自身定义的所有属性(包括不可枚举的),然后筛选出其中类型为函数的那些。这比你想象的要复杂一点点,因为简单的
for...in

要完整地获取一个对象原型链上的所有方法,你需要一个循环来向上追溯原型链,并结合
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
function getAllPrototypeMethods(obj) {
const methods = new Set(); // 使用Set避免重复
let current = obj;
// 循环向上遍历原型链,直到current为null(Object.prototype的原型是null)
while (current) {
// 获取当前原型对象自身的所有字符串属性名(包括不可枚举的)
const propNames = Object.getOwnPropertyNames(current);
// 获取当前原型对象自身的所有Symbol属性名
const symbolProps = Object.getOwnPropertySymbols(current);
// 合并所有属性名
const allProps = [...propNames, ...symbolProps];
allProps.forEach(prop => {
// 尝试获取属性描述符,以判断是否是函数
// 这么做更严谨,因为直接obj[prop]可能会触发getter或报错
try {
const descriptor = Object.getOwnPropertyDescriptor(current, prop);
if (descriptor && typeof descriptor.value === 'function') {
// 确保不是构造函数本身(通常我们不关心这个)
if (prop !== 'constructor') {
methods.add(prop);
}
}
} catch (e) {
// 某些特殊属性可能无法获取描述符,这里简单忽略
// 比如一些宿主对象或Proxy对象
console.warn(`无法获取属性描述符: ${String(prop)}`, e);
}
});
// 向上移动到下一个原型
current = Object.getPrototypeOf(current);
}
return Array.from(methods); // 返回一个数组
}
// 示例用法:
class MyClass {
constructor() {
this.data = 'test';
}
methodA() { return 'A'; }
methodB() { return 'B'; }
static staticMethod() { return 'static'; } // 静态方法不在原型链上
}
Object.prototype.globalMethod = function() { return 'global'; }; // 添加一个可枚举的全局方法
Array.prototype.myArrayMethod = function() { return 'myArray'; }; // 添加一个不可枚举的数组方法
const instance = new MyClass();
const arr = [];
console.log('MyClass实例的方法:', getAllPrototypeMethods(instance));
// 预期输出可能包括:methodA, methodB, toString, valueOf, hasOwnProperty, isPrototypeOf, etc.
console.log('Array实例的方法:', getAllPrototypeMethods(arr));
// 预期输出可能包括:push, pop, shift, unshift, myArrayMethod, map, filter, etc.
console.log('普通对象的方法:', getAllPrototypeMethods({}));
// 预期输出可能包括:toString, valueOf, hasOwnProperty, isPrototypeOf, etc.
// 清理测试用的全局方法,避免污染环境
delete Object.prototype.globalMethod;
delete Array.prototype.myArrayMethod;这段代码基本上涵盖了大部分情况,它会沿着原型链一层层地“剥开”每个原型对象,找出它们“自己”定义的所有方法。我个人觉得,理解原型链这事儿,就像在挖宝藏,一层一层往下刨,每层都有惊喜,也有‘坑’。

for...in
说实话,直接用
for...in
Array.prototype
map
forEach
Object.prototype
toString
hasOwnProperty
for...in
for (let key in []) { console.log(key); }for...in
for...in
hasOwnProperty()
所以,
for...in

区分对象自身的属性和原型链上的方法,这在JavaScript中是个非常基础但又极其重要的概念。核心思想就是“看它是不是直接长在对象身上的”。
最直接、最常用的方法就是使用
Object.prototype.hasOwnProperty.call(obj, propName)
obj
propName
call
obj
hasOwnProperty
然而,对于我们这个“获取原型链上所有方法”的需求,思路稍微有点不同。我们不是要区分一个实例对象
instance
instance
MyClass.prototype
MyClass.prototype
Object.prototype
null
在拿到每一个“原型对象”的时候,我们就要问:“这个原型对象自己有哪些属性?”这时候,
Object.getOwnPropertyNames(protoObj)
Object.getOwnPropertySymbols(protoObj)
protoObj
protoObj
所以,在遍历原型链时,对每个
current
Object.getOwnPropertyNames(current)
Object.getOwnPropertySymbols(current)
function
getOwnPropertyNames
在实际操作中,获取原型链上的方法确实会遇到一些小“坑”和需要注意的地方:
Object.prototype
null
Object.getPrototypeOf(Object.prototype)
null
while (current)
Symbol
Symbol
Object.getOwnPropertyNames()
Symbol
Symbol
Symbol.iterator
Object.getOwnPropertySymbols()
constructor
constructor
constructor
if (prop !== 'constructor')
Object.getOwnPropertyDescriptor()
typeof obj[prop] === 'function'
getter
setter
obj[prop]
Proxy
descriptor.value
__proto__
obj.__proto__
Object.getPrototypeOf()
Object.setPrototypeOf()
window
try...catch
总的来说,获取原型链上的方法,需要你对JavaScript的原型机制、属性特性以及一些内置API有比较深入的理解。这事儿看起来简单,但要做到滴水不漏,还是得细心。
以上就是js如何获取原型链上的所有方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号