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

 alert(show_all_methods(Math));

这应该打印:

abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random,round, sin, sqrt, tan, …

当前回答

我相信有一个简单的历史原因,为什么你不能列举 使用内置对象的方法,例如Array。原因如下:

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

所以IF方法是可枚举的,我将遍历{a:123} 使用:"for(输入{a:123}){…会发生什么?多少次 循环会被执行吗?

在我们的例子中,对于单个键“a”,它将被迭代一次。但也 Object.prototype的每个可枚举属性一次。因此,如果 方法是可枚举的(默认情况下),那么在任何对象上的任何循环都将循环 对所有继承的方法也是如此。

其他回答

受到其他答案的启发,这里有一种查找所有方法的递归方法:

// Find all methods of an object, up to the root prototype
function findAllMethods(obj, methods = []) {
  if (!obj) {
    return [...new Set(methods)];
  }
  
  const props = Object.getOwnPropertyNames(obj);
  return findAllMethods(Object.getPrototypeOf(obj), [
    ...methods,
    ...props.filter(prop => typeof obj[prop] === 'function'),
  ]);
}

如果你想要包括继承方法在内的所有方法:

函数getMethods(obj) { Const方法= []; {做 for (Object.getOwnPropertyNames(obj)的const道具){ if (obj[prop] instanceof Function) method .push(prop); } obj = Object.getPrototypeOf(obj); } while (obj !== null) 回归方法; } console.log (getMethods(数学));

大多数现代浏览器支持console.dir(obj),它将返回它通过构造函数继承的对象的所有属性。有关更多信息和当前浏览器支持,请参阅Mozilla的文档。

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

Math有一个静态方法,你可以直接调用Math.abs(),而Date有一个静态方法,比如Date.now(),还有一个实例方法,你需要先创建一个新的实例var time = new Date()来调用time. gethours()。

// The instance method of Date can be found on `Date.prototype` so you can just call:
var keys = Object.getOwnPropertyNames(Date.prototype);

// And for the static method
var keys = Object.getOwnPropertyNames(Date);

// But if the instance already created you need to
// pass its constructor
var time = new Date();
var staticKeys = Object.getOwnPropertyNames(time.constructor);
var instanceKeys = Object.getOwnPropertyNames(time.constructor.prototype);

当然,您将需要过滤静态方法获得的键,以获得实际的方法名称,因为您还可以获得列表中不是函数的长度和名称。

但是,如果我们想从扩展另一个类的类中获得所有可用的方法,该怎么办呢? 当然,你需要像使用__proto__一样扫描prototype的根。为了节省你的时间,你可以使用下面的脚本来获得静态方法和深层方法实例。

// var keys = new Set(); function getStaticMethods(keys, clas){ var keys2 = Object.getOwnPropertyNames(clas); for(var i = 0; i < keys2.length; i++){ if(clas[keys2[i]].constructor === Function) keys.add(keys2[i]); } } function getPrototypeMethods(keys, clas){ if(clas.prototype === void 0) return; var keys2 = Object.getOwnPropertyNames(clas.prototype); for (var i = keys2.length - 1; i >= 0; i--) { if(keys2[i] !== 'constructor') keys.add(keys2[i]); } var deep = Object.getPrototypeOf(clas); if(deep.prototype !== void 0) getPrototypeMethods(keys, deep); } // ====== Usage example ====== // To avoid duplicate on deeper prototype we use `Set` var keys = new Set(); getStaticMethods(keys, Date); getPrototypeMethods(keys, Date); console.log(Array.from(keys));

如果你想从创建的实例中获取方法,不要忘记传递它的构造函数。

var methods = [];
for (var m in obj) {
    if (typeof obj[m] == "function") {
        methods.push(m);
    }
}
alert(methods.join(","));

这样,你将得到所有你可以在obj上调用的方法。这包括它从原型中“继承”的方法(如java中的getMethods())。如果你只想看到那些由obj直接定义的方法,你可以用hasOwnProperty检查:

var methods = [];
for (var m in obj) {        
    if (typeof obj[m] == "function" && obj.hasOwnProperty(m)) {
        methods.push(m);
    }
}
alert(methods.join(","));