代码之家  ›  专栏  ›  技术社区  ›  GeekTantra

如何显示对象的所有方法?

  •  214
  • GeekTantra  · 技术社区  · 16 年前

    我想知道如何列出对象可用的所有方法,例如:

     alert(show_all_methods(Math));
    

    这应该打印:

    abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random,round, sin, sqrt, tan, …
    
    6 回复  |  直到 8 年前
        1
  •  262
  •   Andy E    11 年前

    你可以使用 Object.getOwnPropertyNames() 获取属于对象的所有属性,无论是否可枚举。例如:

    console.log(Object.getOwnPropertyNames(Math));
    //-> ["E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", ...etc ]
    

    然后你可以使用 filter() 仅获取方法:

    console.log(Object.getOwnPropertyNames(Math).filter(function (p) {
        return typeof Math[p] === 'function';
    }));
    //-> ["random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", ...etc ]
    

    在ES3浏览器(IE8及更低版本)中,内置对象的属性不可枚举。类物体 window document 不是内置的,它们是由浏览器定义的,而且很可能是由设计实现的。

    ECMA-262 Edition 3 以下内容:

    全局对象
    有一个独特的全球 对象(15.1),创建于 控件进入任何执行上下文。 最初,全局对象具有 以下属性:

    内置的 对象,如数学、字符串、日期, 帕森特等 它们有属性{ 唐纳姆 .
    _窆窆定义的附加主机 性质。这可能包括 值为全局的属性 对象本身;例如,在 HTML文档对象建模窗口 全局对象的属性是 全局对象本身。

    作为对照 输入执行上下文,并作为 执行ECMAScript代码, 其他属性可以添加到 全局对象和初始 属性可以更改。

    我应该指出,这意味着这些对象不是全局对象的可枚举属性。如果您查看规范文档的其余部分,您将看到这些对象的大多数内置属性和方法具有 { DontEnum } 对它们设置属性。


    更新:一个同事,所以用户,CMS,带来了 IE bug regarding { DontEnum } 引起我的注意。

    不是检查dontenum属性,[microsoft]jscript将跳过对象原型链中具有dontenum属性的相同命名属性的任何对象中的任何属性。

    简而言之,在命名对象属性时要小心。如果存在具有相同名称的内置原型属性或方法,则IE在使用 for...in 循环。

        2
  •  70
  •   Anurag    16 年前

    ES3不可能,因为属性具有内部 DontEnum 属性阻止我们枚举这些属性。另一方面,ES5为控制属性的枚举功能提供了属性描述符,因此用户定义的和本机属性可以使用相同的接口并享受相同的功能,包括能够以编程方式查看不可枚举的属性。

    这个 getOwnPropertyNames 函数可用于枚举传入对象的所有属性,包括不可枚举的属性。然后是一个简单的 typeof 可以使用check过滤掉非函数。不幸的是,Chrome是目前唯一可以使用的浏览器。

    ​function getAllMethods(object) {
        return Object.getOwnPropertyNames(object).filter(function(property) {
            return typeof object[property] == 'function';
        });
    }
    
    console.log(getAllMethods(Math));
    

    原木 ["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"] 没有特别的顺序。

        3
  •  54
  •   Roland Bouman    16 年前
    var methods = [];
    for (var m in obj) {
        if (typeof obj[m] == "function") {
            methods.push(m);
        }
    }
    alert(methods.join(","));
    

    这样,您将获得所有可以调用的方法 obj . 这包括它从原型“继承”的方法(比如 getMethods() 在Java中)。如果只想查看直接由 OBJ 你可以查一下 hasOwnProperty :

    var methods = [];
    for (var m in obj) {        
        if (typeof obj[m] == "function" && obj.hasOwnProperty(m)) {
            methods.push(m);
        }
    }
    alert(methods.join(","));
    
        4
  •  25
  •   Tsiege Geoff Moller    12 年前

    最现代的浏览器支持 console.dir(obj) ,它将返回通过其构造函数继承的对象的所有属性。查看Mozilla的 documentation 有关详细信息和当前浏览器支持。

    console.dir(Math) => MathConstructor E: 2.718281828459045 LN2: 0.6931471805599453 ... tan: function tan() { [native code] } __proto__: Object

        5
  •  3
  •   Nick Craver    16 年前

    简短的回答是你不能因为 Math Date (在我的头顶上,我确信还有其他物体)不是正常物体。要查看这一点,请创建一个简单的测试脚本:

    <html>
      <body>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
        <script type="text/javascript">
          $(function() {
            alert("Math: " + Math);
            alert("Math: " + Math.sqrt);
            alert("Date: " + Date);
            alert("Array: " + Array);
            alert("jQuery: " + jQuery);
            alert("Document: " + document);
            alert("Document: " + document.ready);
          });
        </script>
      </body>
    </html>
    

    您可以看到它作为一个对象呈现的方式与文档整体呈现的方式相同,但是当您实际尝试在该对象中看到它时,您会看到它是本机代码,并且某些东西对于枚举的呈现方式不一样。

        6
  •  0
  •   Panu Logic    12 年前

    我相信有一个简单的历史原因你不能列举 例如,在数组等内置对象的方法上。这就是为什么:

    方法是原型对象的属性,例如object.prototype。 这意味着所有对象实例都将继承这些方法。那是 为什么可以在任何对象上使用这些方法。比如说.toString()。

    所以,如果方法是可枚举的,并且我将遍历say a:123 用:“for(key in a:123)…”会发生什么?多少次 会执行那个循环吗?

    在我们的示例中,它将对单个键“a”迭代一次。而且 一次一次 可枚举的 object.prototype的属性。所以如果 方法是可枚举的(默认情况下),然后任何对象上的任何循环都将循环 它继承的所有方法也是如此。