Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
js如何获取原型链上的所有方法_创想鸟

js如何获取原型链上的所有方法

要获取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无法访问不可枚举属性、无法区分自有与继承属性等问题,适用于绝大多数标准与非标准场景。

js如何获取原型链上的所有方法

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

for...in

循环并不能满足要求。

js如何获取原型链上的所有方法

解决方案

要完整地获取一个对象原型链上的所有方法,你需要一个循环来向上追溯原型链,并结合

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;

这段代码基本上涵盖了大部分情况,它会沿着原型链一层层地“剥开”每个原型对象,找出它们“自己”定义的所有方法。我个人觉得,理解原型链这事儿,就像在挖宝藏,一层一层往下刨,每层都有惊喜,也有‘坑’。

js如何获取原型链上的所有方法

为什么直接使用

for...in

循环无法获取原型链上的所有方法?

说实话,直接用

for...in

来干这事儿,多半是要碰壁的。它确实能遍历对象的属性,但有几个关键的局限性,导致它无法胜任“获取所有原型链方法”的任务:

只遍历可枚举属性: 这是最主要的问题。JavaScript中很多内置方法(比如

Array.prototype

上的

map

forEach

,或者

Object.prototype

上的

toString

hasOwnProperty

)都是不可枚举的。这意味着它们在

for...in

循环中根本不会出现。你试试看

for (let key in []) { console.log(key); }

,你会发现什么都打不出来,尽管数组有很多方法。遍历自身和继承的属性:

for...in

会遍历对象自身以及原型链上所有可枚举的属性。这意味着它会把原型链上继承来的属性也列出来。如果你只是想知道“这个对象有哪些方法”,那它会给你一堆你可能不想要的信息,而且你还得手动判断哪些是它自己的,哪些是继承的,以及更重要的是,哪些是函数。无法区分属性来源:

for...in

本身并不会告诉你这个属性是对象自己的,还是从原型链上继承来的。你得额外用

hasOwnProperty()

来判断,但这又回到了问题1,因为它同样受限于可枚举性。

所以,

for...in

更适合于遍历那些你明确知道是可枚举的、或者你不在乎它是不是继承来的属性,比如一个配置对象的键值对。对于原型链上的方法查找,它就显得力不从心了。

js如何获取原型链上的所有方法

如何区分对象自身的属性和原型链上的方法?

区分对象自身的属性和原型链上的方法,这在JavaScript中是个非常基础但又极其重要的概念。核心思想就是“看它是不是直接长在对象身上的”。

最直接、最常用的方法就是使用

Object.prototype.hasOwnProperty.call(obj, propName)

。这个方法会检查

obj

是否拥有名为

propName

的“自有”属性(own property),不包括继承来的属性。之所以用

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

属性和方法: JavaScript中除了字符串键名属性,还有

Symbol

作为键名的属性。

Object.getOwnPropertyNames()

只会返回字符串键名的属性,而不会返回

Symbol

键名的属性。如果你的方法使用了

Symbol

作为键名(比如

Symbol.iterator

),那就必须额外使用

Object.getOwnPropertySymbols()

来获取它们。我的解决方案里已经考虑到了这一点。

constructor

属性: 几乎所有对象都会有一个

constructor

属性指向它们的构造函数。这个属性通常也会出现在原型链上。在很多场景下,我们获取“方法”时并不希望包含

constructor

,因为它不是一个常规意义上的“行为”方法。我的代码中加入了

if (prop !== 'constructor')

的判断来过滤掉它,你可以根据自己的需求决定是否保留。属性描述符: 属性不仅有值,还有可写(writable)、可枚举(enumerable)、可配置(configurable)等特性。

Object.getOwnPropertyDescriptor()

可以获取这些详细信息。虽然在判断是否为函数时,直接

typeof obj[prop] === 'function'

通常可行,但如果属性是一个

getter

setter

,直接访问

obj[prop]

可能会触发副作用,或者在某些特殊情况下(如

Proxy

)抛出错误。使用

descriptor.value

来判断会更稳妥一些,虽然增加了代码的复杂性。性能考量: 对于非常深的原型链,或者需要频繁地对大量对象执行此操作时,每次都遍历整个原型链可能会有轻微的性能开销。如果你的应用场景允许,并且对象结构相对稳定,可以考虑对结果进行缓存。

__proto__

的滥用: 早期或者一些非标准的环境中,可能会直接使用

obj.__proto__

来访问和修改原型。虽然它在现代浏览器中广泛支持,但它并不是标准的访问原型链的方式,并且在生产代码中不推荐直接使用。始终坚持使用

Object.getPrototypeOf()

Object.setPrototypeOf()

来操作原型链,这更符合规范,也更安全。宿主对象(Host Objects)的特殊性: 在浏览器环境或Node.js环境中,有些内置对象(如DOM元素、

window

对象)的行为可能与普通JavaScript对象有所不同。它们的一些属性可能无法通过标准方法访问或操作,或者在尝试获取其描述符时抛出错误。我的代码中加入了

try...catch

来处理这种情况,避免程序中断。

总的来说,获取原型链上的方法,需要你对JavaScript的原型机制、属性特性以及一些内置API有比较深入的理解。这事儿看起来简单,但要做到滴水不漏,还是得细心。

以上就是js如何获取原型链上的所有方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1517347.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
什么是Fiber?Fiber的调度算法
上一篇 2025年12月20日 10:42:33
javascript闭包如何暴露有限接口
下一篇 2025年12月20日 10:42:41

相关推荐

  • MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案

    MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案

    mysql的缓存机制主要包括innodb缓冲池、查询缓存和操作系统文件系统缓存等,其中innodb缓冲池是性能优化的核心。1. innodb缓冲池缓存表数据和索引页,减少磁盘i/o,提升读写效率;2. 查询缓存因失效频繁及锁竞争问题,在高并发场景下易成瓶颈,已在mysql 8.0中移除;3. 操作系…

    2026年9月21日 用户投稿
    100
  • 漫番漫画官方网页_ 漫番漫画在线访问入口

    漫番漫画官方网页入口为https://manwa.me,该平台汇聚多类型漫画资源,界面简洁、更新稳定,支持网页端流畅阅读;采用动态域名与镜像站点保障访问连续性,配备HTTPS加密提升安全性;提供个性化阅读设置、书架收藏及评论互动功能,优化用户体验。 漫番漫画官方网页入口地址在哪里?这是不少网友都关注…

    2026年9月21日
    200
  • Chrome浏览器怎么开启数据同步功能_Chrome浏览器跨设备数据同步设置教程

    首先登录Google账户启用Chrome同步功能,确保书签、历史记录、密码等数据跨设备一致;接着在设置中自定义同步内容类型以满足隐私需求;然后通过Google账户密钥或自定义密码加密同步数据,提升安全性;最后在新设备登录同一账户,自动接收已同步的浏览数据,实现无缝体验。 如果您希望在不同设备间无缝使…

    2026年9月21日
    000
  • 如何使用XGBoost训练AI大模型?优化机器学习模型的步骤

    XGBoost并非用于训练GPT类大模型,而是擅长处理结构化数据的高效梯度提升算法,其优势在于速度快、准确性高、支持并行计算、内置正则化与缺失值处理,适用于表格数据建模;通过分阶段超参数调优(如学习率、树深度、采样策略)、结合贝叶斯优化与交叉验证,并配合特征工程、数据预处理和集成学习等关键步骤,可显…

    2026年9月21日
    000
  • VSCode代码编辑器在线使用_VSCode网页版免安装直接进入编辑

    答案:无需安装即可在浏览器使用VSCode,主要方式包括GitHub Codespaces、Gitpod、StackBlitz、CodeSandbox和自托管code-server,适用于不同场景,如GitHub集成、前端开发或完全控制环境;但存在网络依赖、性能限制、插件兼容性、文件访问和安全等局限…

    2026年9月21日
    100
  • 美图秀秀导出视频卡住 美图视频保存失败修复方案

    导出视频卡住或保存失败,通常和设备性能、软件状态或操作方式有关。直接强制退出再尝试是很多人会做的,但更有效的是先排查具体原因。 检查设备资源与软件状态 导出视频是个高负载任务,容易因资源不足中断。 关闭后台应用:尤其是浏览器、游戏或其他大型程序,释放内存和处理器资源。 确认存储空间:确保手机或电脑有…

    2026年9月21日
    000
  • 谷歌浏览器新建窗口无法继承上次会话标签如何解决

    谷歌浏览器新建窗口无法继承上次会话标签如何解决谷歌浏览器新建窗口无法继承上次会话标签如何解决谷歌浏览器新建窗口无法继承上次会话标签如何解决谷歌浏览器新建窗口无法继承上次会话标签如何解决

    答案是检查“启动时”设置并确保选择“继续上次会话”。具体操作为:打开谷歌浏览器设置→启动时→选择“继续上次会话”;新建窗口默认不继承标签页属正常设计,可通过拖拽标签或使用扩展解决;若问题仍存,可检查策略、禁用扩展或重置设置。 谷歌浏览器新建窗口无法继承上次会话的标签页,通常是因为设置未开启或某些配置…

    2026年9月21日 用户投稿
    000
  • VSCode中怎么使用REM_VSCode移动端REM布局编写与换算教程

    答案:REM_VSCode插件可自动将像素转换为REM,需配置rootFontSize和precision,支持自动与手动转换,确保与html的font-size一致,配合media query适配不同屏幕,若插件异常可检查配置、重启或重装,替代工具有postcss-pxtorem、在线转换工具及浏…

    2026年9月21日
    100
  • UC浏览器如何开启省流模式_UC浏览器开启省流模式方法

    开启省流模式可减少UC浏览器流量消耗,通过设置菜单、首页快捷入口或搜索功能三种方式均可启用,系统会压缩网页内容以节省资源。 如果您在使用UC浏览器时希望减少数据流量消耗,尤其是在移动网络环境下,可以通过开启省流模式来优化网页加载方式。该功能会压缩页面内容,降低图片质量和资源体积,从而节省流量。 本文…

    2026年9月21日
    100
  • VSCode怎么新建ipynb文件_VSCode创建和编辑Jupyter笔记本文件教程

    答案:在VSCode中运行Jupyter笔记本需准备Python环境、安装Python扩展并确保安装ipykernel;通过命令面板或文件菜单新建笔记本,编辑时可添加代码或Markdown单元格,运行代码后结果实时显示;通过右上角内核选择器切换Python环境,推荐为不同项目配置独立虚拟环境以避免依…

    2026年9月21日
    200
  • UC浏览器下载速度慢怎么提升_UC浏览器下载速度提升方法

    开启极速模式、更换APN接入点、更改下载路径至内部存储、启用云端加速、清理缓存及切换网络环境可提升UC浏览器下载速度。 如果您在使用UC浏览器下载文件时遇到速度缓慢的问题,这可能是由于网络设置、缓存堆积或下载路径不佳所导致。以下是针对此问题的多种解决方法。 本文运行环境:小米14 Pro,Andro…

    2026年9月21日
    200
  • 夸克Ai搜索如何设置默认_夸克Ai搜索默认引擎更改

    首先在夸克APP中将默认搜索引擎设为AI引擎,再开启相关AI功能开关以启用AI搜索服务。具体步骤:1、打开夸克APP,点击右下角菜单进入设置;2、选择“通用”选项,点击“搜索引擎”;3、选择“AI引擎”或“夸克AI搜索”作为默认服务;4、返回主界面测试搜索关键词,确认AI结果是否展示;5、进入“AI…

    2026年9月21日
    400
  • 百度浏览器自动跳转怎么办 百度浏览器页面跳转广告拦截方法

    百度浏览器自动跳转通常由恶意软件或设置被篡改引起,需检查浏览器设置、清除异常插件、修复快捷方式与注册表,并使用安全软件扫描清理,同时启用广告拦截与隐私保护功能以彻底解决问题。 百度浏览器出现自动跳转,通常不是浏览器本身的问题,而是由恶意软件、插件或设置被篡改导致的。解决这个问题需要从多个方面入手,检…

    2026年9月21日
    100
  • 压力测试(Benchmark)Swoole服务的工具与方法

    进行swoole服务的压力测试是为了确保服务在高负载下稳定运行。1. 选择工具:apache jmeter、wrk、locust。2. 使用方法:jmeter通过脚本配置,wrk通过命令行,locust通过python脚本。3. 注意事项:环境隔离、数据监控、脚本设计。4. 优化点:内存泄漏、连接池…

    2026年9月21日
    000
  • vivo浏览器如何开启硬件加速提升流畅度_vivo浏览器开启硬件加速提升浏览体验的方法

    开启硬件加速可改善vivo手机浏览器卡顿,首先在浏览器设置中查找并开启“硬件加速”功能;若无此选项,可进入系统“开发者选项”,启用“强制进行GPU渲染”;同时建议检查系统更新,确保系统版本最新以保障功能兼容性。 如果您在使用vivo手机内置浏览器时遇到页面加载缓慢或动画卡顿的情况,可能是由于硬件加速…

    2026年9月21日
    000
  • 谷歌浏览器图片无法显示怎么办 谷歌浏览器图片加载失败修复方法

    首先检查浏览器图片显示设置是否允许,确认无误后清除缓存和Cookie数据,接着排查扩展程序干扰,最后更新浏览器并检查硬件加速设置。 谷歌浏览器图片加载不出来,通常不是大问题,多数情况通过几个简单操作就能解决。下面列出几种常见且有效的排查方法。 检查图片显示设置 最直接的原因可能是浏览器被设置为阻止图…

    2026年9月21日
    000
  • 利用蝴蝶号搭建多账号无人直播系统的完整方案

    利用蝴蝶号搭建多账号无人直播系统的完整方案利用蝴蝶号搭建多账号无人直播系统的完整方案利用蝴蝶号搭建多账号无人直播系统的完整方案利用蝴蝶号搭建多账号无人直播系统的完整方案

    搭建多账号无人直播系统并非一键操作,而是通过“蝴蝶号”实现自动化流程。首先,“蝴蝶号”负责多账号的生命周期管理,包括登录、状态维护、ip代理分配和设备指纹模拟;其次,内容调度系统决定直播内容及播放时间,可为预录视频或动态生成流;再次,推流引擎将内容实时推送至平台,推荐使用ffmpeg结合python…

    2026年9月21日 用户投稿
    100
  • MySQL数据库日志审计与合规性实现_保护敏感数据与满足法规需求

    MySQL数据库日志审计与合规性实现_保护敏感数据与满足法规需求MySQL数据库日志审计与合规性实现_保护敏感数据与满足法规需求MySQL数据库日志审计与合规性实现_保护敏感数据与满足法规需求MySQL数据库日志审计与合规性实现_保护敏感数据与满足法规需求

    mysql日志审计是合规性的基石,因为它提供了数据库操作的完整证据链,记录用户身份、操作类型和时间戳等关键信息,满足gdpr、hipaa等法规要求,并支持事后追溯与事前震慑。1. mysql自身提供错误日志、通用查询日志、慢查询日志和二进制日志,其中通用查询日志记录所有sql语句,二进制日志用于数据…

    2026年9月21日 用户投稿
    100
  • 谷歌浏览器官方在线访问 最新版Chrome官网登录

    谷歌浏览器官方在线访问入口是https://www.google.cn/chrome/,提供简洁界面、跨设备同步、高效内核、安全防护和丰富扩展生态。 谷歌浏览器官方在线访问入口在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来最新版Chrome官网登录地址,想要获取纯净浏览体验的网友一起随小…

    2026年9月21日
    200
  • win8怎么更改锁屏壁纸_Win8锁屏壁纸修改方法

    首先通过电脑设置更换锁屏壁纸,进入“锁屏界面”选择图片或浏览自定义图片;其次可通过控制面板跳转至电脑设置完成相同操作;最后可启用幻灯片放映功能,添加文件夹实现锁屏背景自动轮换。 如果您希望个性化您的Windows 8设备,更改锁屏壁纸是一个简单而有效的方式。系统提供了多种途径来替换默认的锁屏背景图片…

    2026年9月21日
    100

发表回复

登录后才能评论
关注微信