Как получить все свойства объекта? - PullRequest
22 голосов
/ 27 декабря 2011

Как получить все свойства объекта, используя отражение в JavaScript?

Ответы [ 4 ]

29 голосов
/ 27 декабря 2011

Переберите объект и возьмите все ключи, которые ему принадлежат и не являются функция:

var properties = [];
for(var key in obj) {
    if(obj.hasOwnProperty(key) && typeof obj[key] !== 'function') {
        properties.push(key);
    }
}
22 голосов
/ 27 декабря 2011

В современных браузерах, чтобы получить все имена свойств (не только перечисляемые свойства), вы должны использовать Object.getOwnPropertyNames ...

var props = Object.getOwnPropertyNames(my_object)

Если вы не хотите перечислимых свойств, вы быиспользуйте Object.keys ...

var props = Object.keys(my_object)
7 голосов
/ 30 декабря 2016

В 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})`);
    }
};

Изучите эту функцию на реальных примерах.

Для встроенного объекта Array

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 ()

Для реального массива (экземпляр объекта Array)

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]}      parammeters 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(' = ');
    });
};

Примечания:

  1. Слабо проверено

  2. Полный код здесь https://github.com/setivolkylany/nodejs-utils

  3. Хороший ресурс по этой теме http://www.2ality.com/2011/01/reflection-and-meta-programming-in.html

  4. Использованы функции ES6

4 голосов
/ 27 декабря 2011
var point = { x:5, y:8 };

for( var name in point ) {
    // name contains the property name that you want
    // point[name] contains the value
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...