JavaScript如何查找函数的所有自有与继承属性
问题原因
Object.keys() 的设计逻辑是仅返回目标对象自身的、可枚举的字符串键属性。
函数实例默认自带的length(形参个数)、name(函数名)、prototype(原型对象)都属于函数的自有属性,但它们的属性描述符中enumerable(可枚举性)被设置为false,自然不会出现在Object.keys()的返回结果里。
你可以用下面的代码验证length的属性特征:
const a = function(a, b, c) {}; console.log(Object.getOwnPropertyDescriptor(a, 'length')); // 输出: {value: 3, writable: false, enumerable: false, configurable: true}
不同场景下获取属性的方法
仅获取对象自身的所有属性(含不可枚举,不含原型链继承)
不要用Object.keys(),改用Object.getOwnPropertyNames()获取所有字符串键的自有属性,搭配Object.getOwnPropertySymbols()获取所有Symbol键的自有属性,两者合并就是完整的自有属性列表:
const a = function(a, b, c) {}; // 自有字符串属性,包含不可枚举的length、name、prototype const ownStrProps = Object.getOwnPropertyNames(a); // 自有Symbol属性,普通函数默认返回空数组 const ownSymbolProps = Object.getOwnPropertySymbols(a); const allOwnProps = [...ownStrProps, ...ownSymbolProps];
获取所有属性(含自有+原型链继承的所有属性,不管是否可枚举)
需要沿着原型链逐层向上遍历,收集每一层原型的自有属性,去重后得到完整结果:
function getAllProperties(obj) { const propSet = new Set(); let current = obj; // 遍历直到原型链顶端null while (current) { // 收集当前层的字符串键属性 Object.getOwnPropertyNames(current).forEach(prop => propSet.add(prop)); // 收集当前层的Symbol键属性 Object.getOwnPropertySymbols(current).forEach(prop => propSet.add(prop)); // 往上走一层原型 current = Object.getPrototypeOf(current); } return Array.from(propSet); } // 测试用例 const a = function(a, b, c) {}; console.log(getAllProperties(a));
返回的结果里,除了函数自身的length、name、prototype,还会包含Function.prototype上的call、apply、bind等方法,以及最顶层Object.prototype上的hasOwnProperty、valueOf等所有继承来的属性。
仅获取所有可枚举属性(含原型链继承)
直接用for...in循环遍历即可,注意这个方法不会返回不可枚举属性,也不会返回Symbol键属性:
const a = function(a, b, c) {}; const enumProps = []; for (const key in a) { enumProps.push(key); }
内容的提问来源于stack exchange,提问作者manymanymore
相关产品推荐
相关产品推荐

