मैं उदाहरण के लिए किसी वस्तु के लिए उपलब्ध सभी तरीकों को सूचीबद्ध करना चाहता हूं:
alert(show_all_methods(Math));
यह प्रिंट होना चाहिए:
abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random,round, sin, sqrt, tan, …
मैं उदाहरण के लिए किसी वस्तु के लिए उपलब्ध सभी तरीकों को सूचीबद्ध करना चाहता हूं:
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) है, जो नियंत्रण से पहले किसी भी निष्पादन संदर्भ में प्रवेश करने पर बनाया जाता है। प्रारंभ में वैश्विक वस्तु में निम्नलिखित गुण होते हैं:• अंतर्निहित वस्तुएं जैसे कि गणित, स्ट्रिंग, तिथि, पार्सइंट, इत्यादि। इनमें विशेषताएँ {DontEnum} हैं ।
• अतिरिक्त होस्ट परिभाषित गुण। इसमें ऐसी संपत्ति शामिल हो सकती है जिसका मूल्य वैश्विक वस्तु है; उदाहरण के लिए, HTML डॉक्यूमेंट ऑब्जेक्ट मॉडल में वैश्विक ऑब्जेक्ट की विंडो प्रॉपर्टी ग्लोबल ऑब्जेक्ट ही होती है।चूंकि नियंत्रण निष्पादन संदर्भों में प्रवेश करता है, और जैसा कि ECMAScript कोड निष्पादित होता है, अतिरिक्त गुणों को वैश्विक ऑब्जेक्ट में जोड़ा जा सकता है और प्रारंभिक गुणों को बदला जा सकता है।
मुझे यह इंगित करना चाहिए कि इसका मतलब यह है कि वे ऑब्जेक्ट ग्लोबल ऑब्जेक्ट के असंख्य गुण नहीं हैं। यदि आप बाकी विनिर्देशन दस्तावेज़ के माध्यम से देखते हैं, तो आप देखेंगे कि इन वस्तुओं के अधिकांश अंतर्निहित गुणों और विधियों में { DontEnum }
विशेषता है।
अद्यतन: एक साथी एसओ उपयोगकर्ता, सीएमएस, मेरे ध्यान से संबंधित{ DontEnum }
एक आईई बग लाया ।
DontEnum विशेषता की जाँच करने के बजाय, [Microsoft] JScript किसी भी ऑब्जेक्ट में किसी भी संपत्ति पर छोड़ देगा जहाँ ऑब्जेक्ट के प्रोटोटाइप श्रृंखला में समान नाम वाली संपत्ति होती है, जिसमें DontEnum विशेषता होती है।
संक्षेप में, अपने ऑब्जेक्ट गुणों का नामकरण करते समय सावधान रहें। यदि एक ही नाम के साथ एक अंतर्निहित प्रोटोटाइप संपत्ति या विधि है, तो IE for...in
लूप का उपयोग करते समय इसे छोड़ देगा ।
Object.getOwnPropertyNames()
, जो कि गैर-विलुप्त होने वाले गुणों और विधियों को भी लौटाएगा।
Object.getOwnPropertyNames(Array.prototype)
?
यह 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
। इसमें वे विधियाँ शामिल हैं जो इसके प्रोटोटाइप से "विरासत में मिली" (जैसे getMethods()
जावा में)। यदि आप केवल उन तरीकों को देखना चाहते हैं जिन्हें obj
आप सीधे परिभाषित कर सकते हैं hasOwnProperty
:
var methods = [];
for (var m in obj) {
if (typeof obj[m] == "function" && obj.hasOwnProperty(m)) {
methods.push(m);
}
}
alert(methods.join(","));
document
किसी चीज़ का उपयोग करता हूं या window
मुझे अधिक भाग्य मिलता है। स्पष्ट रूप से यह थोड़ा अप्रत्याशित है, मुझे नहीं पता कि यह गणित आदि के लिए क्यों काम नहीं करता है
document
और window
ब्राउज़र द्वारा प्रदान की गणनीय गुणों के साथ वस्तुओं रहे हैं, वे पटकथा क्रम का हिस्सा नहीं रहे हैं। मूल वस्तुएं हैं और जाहिर है कि वे गुण नहीं हैं।
अधिकांश आधुनिक ब्राउज़र समर्थन console.dir(obj)
, जो किसी वस्तु के सभी गुणों को वापस कर देगा जो उसे अपने निर्माता के माध्यम से विरासत में मिला है। अधिक जानकारी और वर्तमान ब्राउज़र समर्थन के लिए मोज़िला के दस्तावेज़ देखें ।
console.dir(Math)
=> MathConstructor
E: 2.718281828459045
LN2: 0.6931471805599453
...
tan: function tan() { [native code] }
__proto__: Object
यहाँ अन्य उत्तर कुछ इस तरह से काम करते हैं जैसे कि गणित, जो एक स्थिर वस्तु है। लेकिन वे किसी वस्तु के उदाहरण के लिए काम नहीं करते हैं , जैसे कि एक तारीख। मुझे काम करने के लिए निम्नलिखित मिला:
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/
यह मूल प्रश्न (गणित) जैसी किसी चीज़ के लिए काम नहीं करेगा , इसलिए अपनी आवश्यकताओं के आधार पर अपना समाधान चुनें। मैं इसे यहां पोस्ट कर रहा हूं क्योंकि Google ने मुझे इस प्रश्न पर भेजा था लेकिन मैं जानना चाहता था कि वस्तुओं के उदाहरणों के लिए यह कैसे करना है।
संक्षिप्त उत्तर यह है कि आप ऐसा नहीं कर सकते हैं 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
स्टैटिक मेथड है, जहाँ आप सीधे कॉल कर सकते हैं, 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);
बेशक आपको वास्तविक विधि के नाम प्राप्त करने के लिए स्थिर विधि के लिए प्राप्त कुंजियों को फ़िल्टर करना होगा , क्योंकि आप यह भी प्राप्त कर सकते हैं length, name
कि सूची में कोई फ़ंक्शन नहीं है।
लेकिन अगर हम कक्षा से सभी उपलब्ध विधि प्राप्त करना चाहते हैं जो किसी अन्य वर्ग का विस्तार करें?
बेशक आपको प्रोटोटाइप की जड़ के माध्यम से स्कैन करना होगा जैसे कि उपयोग करना __proto__
। अपना समय बचाने के लिए आप स्टैटिक विधि और डीप मेथड इंस्टेंस प्राप्त करने के लिए नीचे स्क्रिप्ट का उपयोग कर सकते हैं।
// 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));
यदि आप निर्मित आवृत्ति से विधियाँ प्राप्त करना चाहते हैं, तो constructor
इसे पास करना न भूलें ।
मेरा मानना है कि एक साधारण ऐतिहासिक कारण है कि आप उदाहरण के लिए ऐरे जैसी अंतर्निहित वस्तुओं के तरीकों पर अधिक ध्यान नहीं दे सकते। यहाँ पर क्यों:
विधियाँ प्रोटोटाइप-ऑब्जेक्ट के गुण हैं, Object.prototyp कहते हैं। इसका मतलब है कि सभी ऑब्जेक्ट-इंस्टेंस उन विधियों को इनहेरिट करेंगे। इसलिए आप किसी भी ऑब्जेक्ट पर उन तरीकों का उपयोग कर सकते हैं। उदाहरण के लिए .toString () कहें।
तो यदि विधियां अमूल्य थीं, और मैं {a: 123} के साथ कहना चाहूंगा: "for (in a: 123}) {...}" (क्या होगा)? उस पाश को कितनी बार निष्पादित किया जाएगा?
यह हमारे उदाहरण में एकल कुंजी 'a' के लिए एक बार पुनरावृत्त होगा। लेकिन यह भी हर के लिए एक बार गणनीय Object.prototype की संपत्ति। इसलिए यदि विधियाँ अनुप्राणित होती हैं (डिफ़ॉल्ट रूप से), तो किसी भी वस्तु पर कोई भी लूप उसके सभी विरासत में मिले तरीकों पर लूप होगा।
Object.getOwnPropertyNames(Array.prototype)
उदाहरण के लिए संभव है