获取对象原型上的方法最直接的方式是使用 object.getprototypeof() 取得原型对象,再通过 object.getownpropertynames() 配合 filter 筛选出函数类型的自有属性;2. 区分原型方法与实例方法的关键在于 hasownproperty() 检查,实例方法返回 true,原型方法则需沿原型链查找;3. 使用 for...in 时必须结合 hasownproperty() 防止遍历到继承属性,且无法获取不可枚举方法,而 object.getownpropertynames() 可覆盖所有自有属性;4. 避免修改内置对象原型,防止全局污染;5. 原型方法被所有实例共享,节省内存,而实例方法每个实例独有。

JavaScript中要获取一个对象原型上的方法,最直接的方式是先拿到这个对象的原型,然后遍历原型上的属性。你可以通过
Object.getPrototypeOf()
__proto__
Object.getOwnPropertyNames()
for...in
hasOwnProperty

要获取原型上的方法,核心步骤是:首先获取到目标对象的原型对象,然后在这个原型对象上查找它“自己”定义的方法,而不是继承来的方法。
举个例子,我们有一个构造函数
Person

function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
Person.prototype.walk = function() {
console.log(this.name + " is walking.");
};
// 假设我们还给Object.prototype添加了一个方法(不推荐,但用于演示)
// Object.prototype.globalMethod = function() { console.log("Global!"); };
const person1 = new Person("Alice");
// 1. 获取原型对象
const personPrototype = Object.getPrototypeOf(person1);
// 或者使用 person1.__proto__; 但推荐使用 Object.getPrototypeOf(),因为它更标准。
console.log("--- 获取原型上的自有方法 ---");
// 2. 遍历原型对象上的自有属性(方法也是属性)
// Object.getOwnPropertyNames() 会返回所有自有属性的名称,包括不可枚举的
const prototypeMethods = Object.getOwnPropertyNames(personPrototype).filter(name => {
// 确保是函数类型,并且是原型对象自身的属性,而不是继承自更上层原型链的
return typeof personPrototype[name] === 'function' && personPrototype.hasOwnProperty(name);
});
console.log("原型上的方法名称:", prototypeMethods); // 应该输出 ['sayHello', 'walk']
// 如果你想获取方法本身,可以这样:
prototypeMethods.forEach(methodName => {
console.log(`方法名: ${methodName}, 方法体:`, personPrototype[methodName]);
});
// 另一种方法,使用 for...in 循环,但需要额外检查 hasOwnProperty
console.log("\n--- 使用 for...in 配合 hasOwnProperty ---");
for (let key in personPrototype) {
// 确保是原型对象自身的属性,而不是继承自 Object.prototype 等
if (personPrototype.hasOwnProperty(key) && typeof personPrototype[key] === 'function') {
console.log(`通过 for...in 找到的方法: ${key}`);
}
}这里
Object.getOwnPropertyNames()
filter
for...in
hasOwnProperty
有时候,我们确实需要探究一个对象背后,它那些“共享”的能力到底是什么。这不仅仅是为了满足好奇心,它在很多场景下都挺有用的。比如,你在调试一个复杂的库或者框架时,想知道一个特定类型的实例到底有哪些内置的行为,或者它从父类/原型那里继承了哪些方法。直接看实例本身可能只会看到它自己的属性,而那些共享的方法往往藏在原型链上。

再比如说,你想对某个特定类型的所有实例,统一地进行一些“增强”或者“监控”。你不可能去遍历所有实例然后给它们挨个打补丁,更优雅的方式是直接修改它的原型。但在修改之前,你可能需要知道原型上已经有哪些方法了,避免覆盖或者冲突。这就像你拿到一份蓝图,想在上面加点东西,总得先看看蓝图上原本画了些啥吧。
还有一些高级的元编程(meta-programming)场景,比如你想实现一个通用的日志记录器,自动记录某个类所有方法的调用。这时候,你就需要动态地获取这个类原型上的所有方法,然后用代理(Proxy)或者AOP(面向切面编程)的思路去包装它们。这听起来有点复杂,但核心就是“获取原型方法”这个基础操作。
这里面确实有些小坑,一不留神就可能掉进去。
首先,__proto__
Object.getPrototypeOf()
__proto__
Object.getPrototypeOf()
其次,hasOwnProperty
for...in
hasOwnProperty
Object.prototype
toString
valueOf
prototypeObject.hasOwnProperty(key)
再者,不可枚举属性的问题。
for...in
Object.defineProperty
enumerable: false
for...in
Object.getOwnPropertyNames()
Object.getOwnPropertyNames()
最后,一个大大的警告:不要轻易修改内置对象的原型。比如
Array.prototype
String.prototype
区分原型方法和实例方法,其实就是看这个方法是直接定义在对象实例上,还是定义在它的原型链上。这在JavaScript里是个挺核心的概念,理解它能帮助你更好地掌握继承和内存管理。
一个实例方法,顾名思义,就是直接属于这个对象实例的。每次你创建一个新实例,如果这个方法是实例方法,那么每个实例都会有自己独立的一份这个方法的拷贝。比如:
function Car(make, model) {
this.make = make;
this.model = model;
// 这是一个实例方法
this.drive = function() {
console.log(`Driving the ${this.make} ${this.model}.`);
};
}
const myCar = new Car("Honda", "Civic");
const yourCar = new Car("Toyota", "Corolla");
myCar.drive(); // 输出: Driving the Honda Civic.
yourCar.drive(); // 输出: Driving the Toyota Corolla.
// 检查:实例方法直接在实例上
console.log(myCar.hasOwnProperty('drive')); // true而原型方法呢,它是定义在构造函数的
prototype
function Bike(brand) {
this.brand = brand;
}
// 这是一个原型方法
Bike.prototype.ride = function() {
console.log(`Riding the ${this.brand} bike.`);
};
const myBike = new Bike("Giant");
const yourBike = new Bike("Trek");
myBike.ride(); // 输出: Riding the Giant bike.
yourBike.ride(); // 输出: Riding the Trek bike.
// 检查:原型方法不在实例上,而是在其原型上
console.log(myBike.hasOwnProperty('ride')); // false
console.log(Object.getPrototypeOf(myBike).hasOwnProperty('ride')); // true所以,最直接的区分方式就是使用
hasOwnProperty()
obj
methodName
obj.hasOwnProperty(methodName)
true
false
obj.methodName
可以这样来判断:
function checkMethodType(obj, methodName) {
if (obj.hasOwnProperty(methodName) && typeof obj[methodName] === 'function') {
return "实例方法";
}
let proto = Object.getPrototypeOf(obj);
while (proto) {
if (proto.hasOwnProperty(methodName) && typeof proto[methodName] === 'function') {
return "原型方法";
}
proto = Object.getPrototypeOf(proto);
}
return "不是方法或不存在";
}
console.log(checkMethodType(myCar, 'drive')); // 实例方法
console.log(checkMethodType(myBike, 'ride')); // 原型方法
console.log(checkMethodType({}, 'toString')); // 原型方法 (来自 Object.prototype)
console.log(checkMethodType(myCar, 'brake')); // 不是方法或不存在这个
checkMethodType
以上就是js怎么获取原型上的方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号