如何获取对象的所有属性?

Posted

技术标签:

【中文标题】如何获取对象的所有属性?【英文标题】:How to get all properties of an object? 【发布时间】:2012-01-28 04:02:39 【问题描述】:

如何在 javascript 中使用反射获取对象的所有属性?

【问题讨论】:

Javascript reflection - generic toString 的可能重复项 Given an arbitrary javascript object, how can i find its methods?的可能重复 @Brian Roach 为什么重复?和 toString 无关! 【参考方案1】:

遍历对象并获取属于它的每个键,而不是 一个函数:

var properties = [];
for(var key in obj) 
    if(obj.hasOwnProperty(key) && typeof obj[key] !== 'function') 
        properties.push(key);
    

【讨论】:

&& typeof obj[key] !== 'function' 检查没有真正的理由。方法也是属性。【参考方案2】:

在现代浏览器中,要获取所有属性名称(不仅仅是可枚举的属性),您可以使用 Object.getOwnPropertyNames...

var props = Object.getOwnPropertyNames(my_object)

如果您不想要可枚举的属性,您可以使用Object.keys...

var props = Object.keys(my_object)

【讨论】:

【参考方案3】:

JavaScript 没有用于反射(内省)的良好内置工具,因此您需要手动制作。

首先,这里是一个解决方案的代码

/**
 * Display details about an object at run-time
 * @param  [any] target Any object
 * @return Nothing, all information will be display
 */
const introspect = (target) => 
    // get type of a target
    const typeTarget = typeof target;

    // variable for type attribute of the target
    let typeAttr;

    // for properties and methods of the target
    let properties = [];
    let methods = [];

    // if target is array, keep names all enumerable properties, simple put - numbers of indexes
    // otherwise set to null
    const enumerableProperties = Array.isArray(target) ? Object.keys(target) : null;

    // determination functions and properties of the target by a parent object
    Object.getOwnPropertyNames(Object.getPrototypeOf(target)).forEach((name) => 
        if (typeof target[name] === 'function') 
            methods.push(name);
         else if (target.hasOwnProperty(name) && properties.indexOf(name) === -1) 
            properties.push(name);
        
    );

    // determination other functions and properties of the target
    // filter it, if a name already added or if it is an array - filter all values of the indexes
    Object.getOwnPropertyNames(target).forEach((name) => 
        if (enumerableProperties !== null && enumerableProperties.indexOf(name) !== -1) 
            return;
        
        if (typeof target[name] === 'function') 
            methods.push(name);
         else if (target.hasOwnProperty(name) && properties.indexOf(name) === -1) 
            properties.push(name);
        
    );

    // order properties and methods by name in reverse
    properties = properties.reverse();
    methods = methods.reverse();

    // display an obtained information by groups
    console.log(`$typeTarget: "$target"`);
    console.log(`\n\tProperties: $properties.length\n\t------------------`);
    for (let i = properties.length - 1; i >= 0; i -= 1) 
        typeAttr = typeof target[properties[i]];
        console.log(`\t\t$properties[i] --> $typeAttr`);
    

    console.log(`\n\tMethods: $methods.length\n\t------------------`);
    for (let i = methods.length - 1; i >= 0; i -= 1) 
        let args = functools.getFunctionParameters(target[methods[i]]);
        args = args.join(', ');
        console.log(`\t\t$methods[i] ($args)`);
    
;

用实际例子检查这个函数。

对于内置对象数组

introspect(Array);

结果:

function: "function Array()  [native code] "

    Properties: 5
    ------------------
        length --> number
        name --> string
        arguments --> object
        caller --> object
        prototype --> object

    Methods: 8
    ------------------
        apply ()
        bind ()
        call ()
        toString ()
        constructor ()
        isArray ()
        from ()
        of ()

对于真实数组(对象数组的实例)

introspect([-10, '20', true, []]);

结果:

object: "-10,20,true,"

    Properties: 1
    ------------------
        length --> number

    Methods: 29
    ------------------
        constructor ()
        toString ()
        toLocaleString ()
        join ()
        pop ()
        push ()
        reverse ()
        shift ()
        unshift ()
        slice ()
        splice ()
        sort ()
        filter ()
        forEach ()
        some ()
        every ()
        map ()
        indexOf ()
        lastIndexOf ()
        reduce ()
        reduceRight ()
        copyWithin ()
        find ()
        findIndex ()
        fill ()
        includes ()
        entries ()
        keys ()
        concat ()

真实的物体呢?

introspect(
    aa: 1,
    bb: true,
    cc: [],
    dd: ,
    c: (z, a= 2) => ,
    b: function(z   =  1, a=2) ,
    d: function(b, zzz) ,
);

结果:

object: "[object Object]"

    Properties: 4
    ------------------
        aa --> number
        bb --> boolean
        cc --> object
        dd --> object

    Methods: 14
    ------------------
        hasOwnProperty ()
        constructor ()
        toString ()
        toLocaleString ()
        valueOf ()
        isPrototypeOf ()
        propertyIsEnumerable ()
        __defineGetter__ ()
        __lookupGetter__ ()
        __defineSetter__ ()
        __lookupSetter__ ()
        c (z, a = 2)
        b (z = 1, a = 2)
        d (b, zzz)

此功能也可以很好地与内置模块一起使用。内省 Math 模块。

introspect(Math);

结果

object: "[object Math]"

    Properties: 8
    ------------------
        E --> number
        LN10 --> number
        LN2 --> number
        LOG2E --> number
        LOG10E --> number
        PI --> number
        SQRT1_2 --> number
        SQRT2 --> number

    Methods: 46
    ------------------
        hasOwnProperty ()
        constructor ()
        toString ()
        toLocaleString ()
        valueOf ()
        isPrototypeOf ()
        propertyIsEnumerable ()
        __defineGetter__ ()
        __lookupGetter__ ()
        __defineSetter__ ()
        __lookupSetter__ ()
        acos ()
        asin ()
        atan ()
        ceil ()
        clz32 ()
        floor ()
        fround ()
        imul ()
        max ()
        min ()
        round ()
        sqrt ()
        trunc ()
        random ()
        abs ()
        exp ()
        log ()
        atan2 ()
        pow ()
        sign ()
        asinh ()
        acosh ()
        atanh ()
        hypot ()
        cbrt ()
        cos ()
        sin ()
        tan ()
        sinh ()
        cosh ()
        tanh ()
        log10 ()
        log2 ()
        log1p ()
        expm1 ()

什么污染回答多余代码,自己动手试试看结果

introspect(34.2313);
introspect(true);
introspect(Date);
introspect((new Date()));
introspect(String);
introspect('text');

对于完整的代码,我还展示了函数“getFunctionParameters”(在模块“functools.js”中),因为它使用了它。

/**
 * Return array paraments of a function
 * @param  [function] func function
 * @return [array]      parameters the functions
 *
 */
const getFunctionParameters = (func) => 
    if (typeof func !== 'function') 
        throw new Error('A argument is not function.');
    
    const args = func.toString().match(/\((.*)\)/)[1];
    return args.split(',').map((arg) => 
        if (arg.indexOf('=') === -1) return arg.trim();
        return arg
            .split('=')
            .map(val => val.trim())
            .join(' = ');
    );
;

注意事项:

    弱测试

    这里有完整代码https://github.com/setivolkylany/nodejs-utils

    关于它的好资源主题http://www.2ality.com/2011/01/reflection-and-meta-programming-in.html

    使用了 ES6 的特性

【讨论】:

【参考方案4】:
var point =  x:5, y:8 ;

for( var name in point ) 
    // name contains the property name that you want
    // point[name] contains the value

【讨论】:

以上是关于如何获取对象的所有属性?的主要内容,如果未能解决你的问题,请参考以下文章

php如何打印对象的所有属性

如何从一行列表中的所有对象中获取相同的属性

如何获取与 Typescript 中的接口匹配的对象的所有属性? [复制]

如何获取所有对象A的一对多关系B的所有属性的NSSet

如何反射取得一个对象中所有字段的值

与第一个对象进行比较时,如何获取第二个对象数组的所有属性?