Как отобразить все методы объекта? - PullRequest
224 голосов
/ 13 февраля 2010

Я хочу знать, как перечислить все методы, доступные для объекта, например:

 alert(show_all_methods(Math));

Это должно напечатать:

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

Ответы [ 6 ]

270 голосов
/ 13 февраля 2010

Вы можете использовать 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 (IE 8 и ниже) свойства встроенных объектов не перечисляются. Такие объекты, как window и document не являются встроенными, они определены браузером и, скорее всего, могут быть перечислены по проекту.

С ECMA-262 Edition 3 :

Глобальный объект
Существует уникальный глобальный объект (15.1), который создается ранее управление входит в любой контекст выполнения. Первоначально глобальный объект имеет следующие свойства:

• Встроенный объекты, такие как Math, String, Date, parseInt и т. д. Они имеют атрибуты { DontEnum} .
• Определен дополнительный хост свойства. Это может включать в себя свойство, значение которого является глобальным сам объект; например, в HTML документ объектная модель окна Свойство глобального объекта является сам глобальный объект.

как контроль входит в контексты исполнения, и как Код ECMAScript выполнен, дополнительные свойства могут быть добавлены к глобальный объект и начальный свойства могут быть изменены.

Я должен отметить, что это означает, что эти объекты не являются перечисляемыми свойствами Глобального объекта. Если вы посмотрите остальную часть документа спецификации, вы увидите, что для большинства встроенных свойств и методов этих объектов установлен атрибут { DontEnum }.


Обновление: один из пользователей SO, CMS, сообщил мне IE об ошибке { DontEnum }.

Вместо проверки атрибута DontEnum [Microsoft] JScript пропустит любое свойство в любом объекте, где есть свойство с таким же именем в цепочке прототипов объекта, имеющего атрибут DontEnum.

Короче, будьте осторожны при именовании свойств вашего объекта. Если есть встроенное свойство или метод-прототип с таким же именем, то IE пропустит его при использовании цикла for...in.

70 голосов
/ 01 июня 2010

Это невозможно с ES3, поскольку свойства имеют внутренний атрибут DontEnum, который запрещает нам перечислять эти свойства. ES5, с другой стороны, предоставляет дескрипторы свойств для управления возможностями перечисления свойств, чтобы пользовательские и собственные свойства могли использовать один и тот же интерфейс и пользоваться теми же возможностями, что включает возможность программно просматривать не перечисляемые свойства.

Функция getOwnPropertyNames может использоваться для перечисления всех свойств переданного объекта, включая те, которые не перечисляются. Затем можно применить простую проверку typeof, чтобы отфильтровать не-функции. К сожалению, 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"] в произвольном порядке.

55 голосов
/ 13 февраля 2010
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(","));
27 голосов
/ 22 февраля 2010

Большинство современных браузеров поддерживают console.dir(obj), который возвращает все свойства объекта, которые он унаследовал через конструктор. См. документацию Mozilla для получения дополнительной информации и текущей поддержки браузера.

console.dir(Math)
=> MathConstructor
E: 2.718281828459045
LN2: 0.6931471805599453
...
tan: function tan() { [native code] }
__proto__: Object
3 голосов
/ 13 февраля 2010

Короткий ответ: вы не можете, потому что 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>

Вы видите, что он представлен как объект точно так же, как документ в целом, но когда вы на самом деле пытаетесь увидеть этот объект, вы видите, что это нативный код и что-то не доступно для перечисления.

0 голосов
/ 26 января 2014

Я считаю, что есть простая историческая причина, почему вы не можете перечислить над методами встроенных объектов, таких как, например, Array. И вот почему:

Методы - это свойства объекта-прототипа, скажем, Object.prototype. Это означает, что все экземпляры Object будут наследовать эти методы. Это почему вы можете использовать эти методы на любом объекте. Скажем, например .toString ().

Таким образом, если методы были перечислимы, и я бы повторил, скажем {a: 123} с: "for (введите {a: 123}) {...}" что произойдет? Сколько раз этот цикл будет выполнен?

В нашем примере это будет повторяться один раз для единственного ключа 'a'. НО ТАКЖЕ один раз для каждого перечисляемого свойства Object.prototype. Так что если методы были перечисляемы (по умолчанию), тогда любой цикл над любым объектом был бы зациклен по всем его унаследованным методам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...