如何查找网页中使用的所有JavaScript类定义
问题
是否存在方法可以查找网页中用到的所有唯一类定义?例如某网页包含三个互不相关的JS类Dog、Cat、Mouse,在预先不知道这些类存在的前提下,要如何发现它们?
需要补全如下可直接在Chrome控制台运行的函数:
//returns all the JS classes in a document function getAllDocumentClasses(){ }
背景
我正在编写使用JavaScript提取网页数据的相关文档,其中一种数据提取思路是探查页面所用第三方库包含的类,例如查找页面中所有Highcharts实例,再提取实例内存储的业务数据;但如果预先不知道网页加载了哪些第三方库,该方案的实现难度会大幅提升。
目前观察到打开Chrome开发者工具后输入window.,即可浏览全局window对象下所有可用的类,但纯JS似乎无法完全覆盖所有类定义。
实现方案
核心判断逻辑基于ES规范:所有class关键字定义的类,调用Function.prototype.toString()返回的字符串一定以class开头,和普通构造函数有明确区分。遍历从全局window对象出发,递归遍历所有可达属性,同时做循环引用防护、异常捕获避免跨域/受限属性报错,默认过滤JS和DOM内置类。
可直接在Chrome控制台运行的完整代码:
function getAllDocumentClasses(includeBuiltIn = false) { const classSet = new Set(); const visitedRef = new WeakSet(); // 内置类黑名单,默认过滤 const builtInList = new Set([ 'Object', 'Array', 'Function', 'Boolean', 'String', 'Number', 'Date', 'RegExp', 'Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Promise', 'Map', 'Set', 'WeakMap', 'WeakSet', 'ArrayBuffer', 'SharedArrayBuffer', 'DataView', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'BigInt', 'BigInt64Array', 'BigUint64Array', 'Symbol', 'Proxy', 'Reflect', 'JSON', 'Math', 'Window', 'Document', 'Element', 'Node', 'Event', 'HTMLElement' ]); function walk(target) { if (!target || (typeof target !== 'object' && typeof target !== 'function')) return; if (visitedRef.has(target)) return; visitedRef.add(target); // 校验当前目标是否为类 if (typeof target === 'function') { const isClass = /^class\s/.test(Function.prototype.toString.call(target)); if (isClass) { const name = target.name || '(匿名类)'; if (includeBuiltIn || !builtInList.has(name)) { classSet.add(target); } } } // 遍历所有自有属性(含不可枚举属性) const props = Object.getOwnPropertyNames(target); for (const prop of props) { try { walk(target[prop]); } catch (err) { // 跳过跨域、权限限制无法访问的属性 } } } walk(window); return Array.from(classSet); }
使用说明
- 直接将上述代码粘贴到Chrome控制台回车执行完成函数定义
- 调用
getAllDocumentClasses()即可拿到页面所有自定义类、第三方库暴露的类,返回结果是类构造函数的数组 - 如果需要同时返回JS、DOM内置类,传参调用
getAllDocumentClasses(true)即可
局限性说明
- 无法捕获定义在闭包内、未挂载到任何全局可达对象上的类,这类类属于JS词法作用域隔离的内容,外部没有通用访问手段
- 受浏览器同源策略限制,无法遍历跨域iframe内的类定义
- 部分经过极端混淆、篡改了
Function.prototype.toString逻辑的场景可能存在漏判,这种场景没有通用识别方案
内容的提问来源于stack exchange,提问作者ANimator120
相关产品推荐
相关产品推荐

