たとえば、次のように、オブジェクトに使用できるすべてのメソッドを一覧表示する方法を知りたいです。
alert(show_all_methods(Math));
これは印刷する必要があります:
abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random,round, sin, sqrt, tan, …
列挙型かどうかにかかわらず、オブジェクトに属するすべてのプロパティを取得するには、 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第3版 :
グローバルオブジェクト
制御が実行コンテキストに入る前に作成される一意のグローバルオブジェクト(15.1)があります。グローバルオブジェクトは、最初は以下のプロパティを持っています。•Math、String、Date、parseIntなどの組み込みオブジェクトこれらには属性{DontEnum}があります。
•追加のホスト定義プロパティ。これには、グローバルオブジェクト自体を値とするプロパティが含まれる場合があります。たとえば、HTMLドキュメントオブジェクトモデルでは、グローバルオブジェクトのwindowプロパティはグローバルオブジェクト自体です。制御が実行コンテキストに入ったとき、およびECMAScriptコードが実行されたときに、追加のプロパティがグローバルオブジェクトに追加され、初期プロパティが変更される場合があります。
これは、これらのオブジェクトがGlobalオブジェクトの列挙型プロパティではないことを意味することを指摘しておく必要があります。仕様書の残りの部分を見ると、これらのオブジェクトのほとんどの組み込みプロパティとメソッドには{ DontEnum }
属性が設定されています。
最新情報:SO他のユーザー、CMSが IEの{ DontEnum }
に関するバグ を私の注意を引いた。
DontEnum属性をチェックする代わりに、[Microsoft] JScriptは、オブジェクトのプロトタイプチェーン内にDontEnum属性を持つ同名のプロパティがあるオブジェクト内のプロパティをすべてスキップします。
つまり、オブジェクトのプロパティに名前を付けるときは注意してください。同じ名前の組み込みのプロトタイププロパティまたはメソッドがある場合、IEはfor...in
ループを使用するときにそれをスキップします。
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"]
を特定の順序で記録しません。
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(","));
最近のほとんどのブラウザはconsole.dir(obj)
をサポートしています。これはコンストラクタを通して継承したオブジェクトのすべてのプロパティを返します。さらなる情報と現在のブラウザサポートについてはMozillaの ドキュメント を参照してください。
console.dir(Math)
=> MathConstructor
E: 2.718281828459045
LN2: 0.6931471805599453
...
tan: function tan() { [native code] }
__proto__: Object
簡単に言えば、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>
あなたはそれがオブジェクトとしてドキュメントが全体的に行うのと同じ方法で提示されているのを見ますが、実際にそのオブジェクトを試してみると、それはネイティブコードであり列挙のために同じ方法を公開していないことがわかります。
ここでの他の回答は、静的オブジェクトであるMathのようなものに有効です。ただし、日付などのオブジェクトのインスタンスでは機能しません。私は次のことを見つけました:
function getMethods(o) {
return Object.getOwnPropertyNames(Object.getPrototypeOf(o))
.filter(m => 'function' === typeof o[m])
}
//example: getMethods(new Date()): [ 'getFullYear', 'setMonth', ... ]
https://jsfiddle.net/3xrsead0/
このは元の質問(Math)のようなものでは機能しないため、ニーズに基づいてソリューションを選択してください。 Googleがこの質問に私を送ったので、私はこれをここに投稿していますが、オブジェクトのインスタンスに対してこれを行う方法を知りたいと思っていました。
たとえばArrayのような組み込みオブジェクトのメソッドを列挙できないのは、歴史的に単純な理由があると思います。これが理由です:
メソッドはプロトタイプオブジェクトのプロパティです、Object.prototype。つまり、すべてのObjectインスタンスはこれらのメソッドを継承します。だからこそ、これらのメソッドをどのオブジェクトでも使用できるのです。例えば.toString()としてください。
それでIFメソッドは列挙可能でした、そして、私は{a:123}を言って繰り返します: "for(key in {a:123}){...}"何が起こるでしょう?そのループは何回実行されるでしょうか。
この例では、単一のキー 'a'に対して1回繰り返されます。ただし、Object.prototypeの列挙可能プロパティごとに1回ずつも。そのため、メソッドが(デフォルトで)列挙可能な場合、任意のオブジェクトに対するループは、継承されているすべてのメソッドに対してもループします。