【问题标题】:Given an arbitrary javascript object, how can i find its methods?给定一个任意的 javascript 对象,我怎样才能找到它的方法?
【发布时间】:2010-07-15 04:12:50
【问题描述】:

我知道这在 python 中是可能的,但是我可以得到一个 javascript 对象的方法列表吗?

【问题讨论】:

    标签: javascript reflection


    【解决方案1】:

    您可以遍历对象中的属性并测试它们的类型。

    for(var prop in whatever) {
        if(typeof whatever[prop] == 'function') {
            //do something
        }
    }
    

    【讨论】:

    • 没有。无论如何,所有原生 JavaScript 函数都接受任意数量的参数。
    • @deostroll 在实现 toSource 的浏览器中,目前只有 firefox,可以使用func.toSource().match(/\(([^\(\)]+)\)/)[1]。不过,这不适用于内置函数。
    【解决方案2】:

    要添加到现有答案,ECMAScript 第 5 版。提供了一种使用方法Object.getOwnPropertyNames 访问对象的所有属性(甚至是不可枚举的属性)的方法。在尝试枚举原生对象的属性时,例如Mathfor..in

    for(var property in Math) {
        console.log(property);
    }
    

    不会在控制台上打印任何内容。然而,

    Object.getOwnPropertyNames(Math)
    

    将返回:

    ["LN10", "PI", "E", "LOG10E", "SQRT2", "LOG2E", "SQRT1_2", "abc", "LN2", "cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]
    

    您可以在此基础上编写一个仅返回给定对象的方法的辅助函数。

    function getMethods(object) {
        var properties = Object.getOwnPropertyNames(object);
        var methods = properties.filter(function(property) {
            return typeof object[property] == 'function';
        });
        return methods;
    }
    
    > getMethods(Math)
    ["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]
    

    支持 ECMAScript 第 5 版。在这一点上有点暗淡,因为只有 Chrome、IE9pre3 和 Safari/Firefox nightlies 支持它。

    【讨论】:

    • +1,我看不出有任何反对意见的理由。顺便说一句,IE9pre3 也支持它。
    • 感谢@CMS,很高兴看到 IE 与 v9 保持同步。更新了答案。
    • 是的,我真的很高兴看到 IE9 走上正轨,我只发现了一些关于属性描述符和 Object.create 的错误 (8+),希望这个周末我能得到一些是时候报告他们了。 :)
    【解决方案3】:

    这个函数接收一个任意对象并返回它的原型名称、一个包含它所有方法的列表和一个包含它的属性(及其类型)名称的对象。我没有机会在浏览器中测试它,但它适用于 Nodejs (v0.10.24)。

    function inspectClass(obj) {    
        var objClass, className;   
        var classProto;
        var methods = [];
        var attributes = {};
        var t, a;
        try {
            if (typeof(obj) != 'function') {
                objClass = obj.constructor;
            } else {
                objClass = obj;      
            }
            className = objClass.name;
            classProto = objClass.prototype        
            Object.getOwnPropertyNames(classProto).forEach(function(m) {
                t = typeof(classProto[m]);
                if (t == 'function') {
                    methods.push(m);
                } else {
                    attributes[m] = t;
                }       
            });
        } catch (err) {
            className = 'undefined';
        }
        return { 'ClassName' : className,
                 'Methods' : methods,
                 'Attributes' : attributes
        }
    }
    

    示例(使用 Nodejs):

    console.log(inspectClass(new RegExp("hello")));
    

    输出:

    { ClassName: 'RegExp',
      Methods: [ 'constructor', 'exec', 'test', 'toString', 'compile' ],
      Attributes: 
       { source: 'string',
         global: 'boolean',
         ignoreCase: 'boolean',
         multiline: 'boolean',
         lastIndex: 'number' } }
    

    以下示例也适用于 Nodejs:

    console.log(inspectClass(RegExp));
    console.log(inspectClass("hello"));
    console.log(inspectClass(5));
    console.log(inspectClass(undefined));
    console.log(inspectClass(NaN));
    console.log(inspectClass(inspectClass));
    

    【讨论】:

      【解决方案4】:

      单行解决方案

      Object.getOwnPropertyNames(JSON).filter(function(name){ return 'function' === typeof JSON[name]; })
      

      ['解析','字符串化']

      Object.getOwnPropertyNames(String).filter(function(name){ return 'function' === typeof String[name]; })
      

      [ 'fromCharCode', 'fromCodePoint', 'raw' ]

      Object.getOwnPropertyNames(Array).filter(function(name){ return 'function' === typeof Array[name]; })
      

      [ 'isArray', '来自', 'of' ]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        相关资源
        最近更新 更多