当前位置:首页 > 文章列表 > 文章 > 前端 > JS获取对象原型方法详解

JS获取对象原型方法详解

2025-08-07 23:36:33 0浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《JS如何获取对象原型方法》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

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

js怎么获取原型上的方法

JavaScript中要获取一个对象原型上的方法,最直接的方式是先拿到这个对象的原型,然后遍历原型上的属性。你可以通过 Object.getPrototypeOf() 方法或者非标准的 __proto__ 属性来获取原型对象,接着再用 Object.getOwnPropertyNames()for...in 循环(配合 hasOwnProperty 检查)来列出这些方法。

js怎么获取原型上的方法

解决方案

要获取原型上的方法,核心步骤是:首先获取到目标对象的原型对象,然后在这个原型对象上查找它“自己”定义的方法,而不是继承来的方法。

举个例子,我们有一个构造函数 Person

js怎么获取原型上的方法
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 来确保我们只拿原型对象自身的属性。

为什么我们需要获取原型上的方法?

有时候,我们确实需要探究一个对象背后,它那些“共享”的能力到底是什么。这不仅仅是为了满足好奇心,它在很多场景下都挺有用的。比如,你在调试一个复杂的库或者框架时,想知道一个特定类型的实例到底有哪些内置的行为,或者它从父类/原型那里继承了哪些方法。直接看实例本身可能只会看到它自己的属性,而那些共享的方法往往藏在原型链上。

js怎么获取原型上的方法

再比如说,你想对某个特定类型的所有实例,统一地进行一些“增强”或者“监控”。你不可能去遍历所有实例然后给它们挨个打补丁,更优雅的方式是直接修改它的原型。但在修改之前,你可能需要知道原型上已经有哪些方法了,避免覆盖或者冲突。这就像你拿到一份蓝图,想在上面加点东西,总得先看看蓝图上原本画了些啥吧。

还有一些高级的元编程(meta-programming)场景,比如你想实现一个通用的日志记录器,自动记录某个类所有方法的调用。这时候,你就需要动态地获取这个类原型上的所有方法,然后用代理(Proxy)或者AOP(面向切面编程)的思路去包装它们。这听起来有点复杂,但核心就是“获取原型方法”这个基础操作。

获取原型方法时常见的陷阱和注意事项有哪些?

这里面确实有些小坑,一不留神就可能掉进去。

首先,__proto__Object.getPrototypeOf() 的选择。虽然 __proto__ 用起来很方便,但它曾经是一个非标准的属性,现在虽然在大多数浏览器和Node.js环境中都支持了,但从规范性和兼容性角度来说,Object.getPrototypeOf() 才是官方推荐和更稳妥的选择。尤其是当你在编写需要长期维护或者跨环境运行的代码时,坚持使用标准API总是没错的。

其次,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版本更新时出现不可预测的问题。这就像你在一个公共的交通枢纽里随意更改路标,虽然你觉得方便了自己,但可能会让其他人迷失方向。所以,获取原型方法通常是为了理解、分析或者在受控环境下进行操作,而不是为了肆意修改。

如何区分原型方法和实例方法?

区分原型方法和实例方法,其实就是看这个方法是直接定义在对象实例上,还是定义在它的原型链上。这在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获取对象原型方法详解》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

JavaScript如何用isEqual比较数组相等JavaScript如何用isEqual比较数组相等
上一篇
JavaScript如何用isEqual比较数组相等
判断对象是否被冻结的方法
下一篇
判断对象是否被冻结的方法
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    511次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    498次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 千音漫语:智能声音创作助手,AI配音、音视频翻译一站搞定!
    千音漫语
    千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
    124次使用
  • MiniWork:智能高效AI工具平台,一站式工作学习效率解决方案
    MiniWork
    MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
    122次使用
  • NoCode (nocode.cn):零代码构建应用、网站、管理系统,降低开发门槛
    NoCode
    NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
    135次使用
  • 达医智影:阿里巴巴达摩院医疗AI影像早筛平台,CT一扫多筛癌症急慢病
    达医智影
    达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
    130次使用
  • 智慧芽Eureka:更懂技术创新的AI Agent平台,助力研发效率飞跃
    智慧芽Eureka
    智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
    132次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码