如何列出JavaScript对象中非基类/继承类的新增成员
如何实现ListNewMemberNames函数获取window的新增成员?
我不确定怎么定义这类"新增成员",看下面的示例,我需要实现ListNewMemberNames函数。以下代码(demo.html)假定在浏览器环境运行:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Var1 Test</title> </head> <body> <script> var1 = {value:7} /* 等同于 window.var1 = {value:7}*/ ListMemberNames(window) /* 返回: ["__defineGetter__", ... "addEventListener", "alert", ... "var1"] */ ListNewMemberNames(window) /* 返回: ["var1"] */ function ListMemberNames(obj){ /* 用.hasOwnProperty()之类的技巧实现*/ } function ListNewMemberNames(obj){ /* 该怎么写? */ } </script> </body> </html>
示例里ListMemberNames会返回window的所有成员,而ListNewMemberNames只需要返回其中新增的成员(比如var1)。
实现思路
核心是提前记录window的原生成员集合,之后对比当前window的成员,筛选出不在原生集合里的项——因为浏览器加载页面后,window自带大量原生属性和方法,我们要区分这些原生项和用户后来新增的项。
具体实现代码
完整demo.html代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Var1 Test</title> <script> // 关键:在所有自定义代码之前保存window的原生成员 const originalWindowMembers = new Set(Object.getOwnPropertyNames(window)); </script> </head> <body> <script> var1 = {value:7} /* 等同于 window.var1 = {value:7}*/ console.log(ListMemberNames(window)); /* 返回包含原生成员和var1的数组 */ console.log(ListNewMemberNames(window)); /* 仅返回 ["var1"] */ function ListMemberNames(obj){ // 返回对象自身的所有属性(包括不可枚举的) return Object.getOwnPropertyNames(obj); } function ListNewMemberNames(obj){ // 筛选出不在原生成员集合里的项 return Object.getOwnPropertyNames(obj).filter(name => !originalWindowMembers.has(name)); } </script> </body> </html>
细节说明
- 用
Object.getOwnPropertyNames的原因:它会返回对象自身的所有属性(包括不可枚举的),比for...in或Object.keys更全面,能覆盖window的所有原生成员。 - 用
Set存储原生成员:Set.has()的查询效率远高于数组的indexOf,在成员数量多的时候性能更好。 - 代码位置要求:保存原生成员的代码必须放在页面最开头的
<script>里,确保在任何自定义变量、第三方脚本执行前运行,这样才能准确拿到纯净的window原生成员列表。
内容的提问来源于stack exchange,提问作者Byzod
相关产品推荐
相关产品推荐

