किसी ऑब्जेक्ट के प्रकार का नाम प्राप्त करें


1193

वहाँ एक है जावास्क्रिप्ट के बराबर जावा के class.getName()?


यह सवाल यह है कि हम जानते हैं कि जावा का class.getName () क्या करता है। चूंकि मुझे नहीं लगता कि मुझे यकीन नहीं है कि उत्तर मुझे मदद करेंगे।
2:34 बजे user34660

2
@ user34660 मुझे लगता है कि हम सुरक्षित रूप से मान सकते हैं कि यह जो करता है उसे एक वस्तु के प्रकार का नाम मिलता है।
स्टैक अंडरफ्लो

1
@StackUnderflow: को छोड़कर, यह वास्तव में नहीं है। इसे किसी वस्तु के वर्ग का नाम मिलता है , जो वस्तु के प्रकार के समान नहीं है ।
जार्ज डब्ल्यू मित्तग

1
@ JörgWMittag आह, बिल्कुल। हां देखें कि क्या होता है जब आप चीजों को सुरक्षित रूप से ग्रहण करते हैं?
स्टैक अंडरफ्लो

जवाबों:


1540

क्या जावा के बराबर जावास्क्रिप्ट है class.getName()?

नहीं

ES2015 अपडेट : का नाम class Foo {}हैFoo.namething'S वर्ग का नाम , भले ही किसी भी thingप्रकार का हो thing.constructor.name। ES2015 वातावरण में निर्मित बिल्डरों के पास सही nameसंपत्ति है; उदाहरण के लिए (2).constructor.nameहै "Number"


लेकिन यहां विभिन्न हैक हैं जो सभी एक या दूसरे तरीके से नीचे आते हैं:

यहां एक हैक है जो आपको आवश्यकता होगी - यह ध्यान रखें कि यह ऑब्जेक्ट के प्रोटोटाइप को संशोधित करता है, कुछ लोग (आमतौर पर अच्छे कारण के लिए) पर फेंक देते हैं

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

अब, आपकी सभी वस्तुओं में फ़ंक्शन getName()होगा, जो एक स्ट्रिंग के रूप में कंस्ट्रक्टर का नाम लौटाएगा। मैं इस परीक्षण किया है FF3और IE7, मैं अन्य कार्यान्वयन के लिए बात नहीं कर सकते।

यदि आप ऐसा नहीं करना चाहते हैं, तो यहां जावास्क्रिप्ट में प्रकारों के निर्धारण के विभिन्न तरीकों पर चर्चा की गई है ...


मैंने हाल ही में इसे थोड़ा और अधिक थकाऊ होने के लिए अद्यतन किया है, हालांकि यह शायद ही ऐसा हो। सुधार का स्वागत ...

constructorसंपत्ति का उपयोग ...

प्रत्येक के objectपास अपनी constructorसंपत्ति के लिए एक मूल्य है , लेकिन यह इस बात पर निर्भर करता है कि उस objectनिर्माण के साथ-साथ आप उस मूल्य के साथ क्या करना चाहते हैं, यह उपयोगी हो सकता है या नहीं।

आम तौर पर बोलकर, आप constructorसंपत्ति का उपयोग वस्तु के प्रकार का परीक्षण करने के लिए कर सकते हैं :

var myArray = [1,2,3];
(myArray.constructor == Array); // true

तो, यह ज्यादातर जरूरतों के लिए पर्याप्त काम करता है। ने कहा कि...

चेतावनियां

कई मामलों में सभी पर काम नहीं करेगा

यह पैटर्न, हालांकि टूटा हुआ है, काफी सामान्य है:

function Thingy() {
}
Thingy.prototype = {
    method1: function() {
    },
    method2: function() {
    }
};

Objectsद्वारा new Thingyबनाई गई एक constructorसंपत्ति होगी जो इंगित करती है Object, नहीं Thingy। तो हम शुरुआत में ही गिर जाते हैं; आप बस constructorएक कोडबेस पर भरोसा नहीं कर सकते हैं जिसे आप नियंत्रित नहीं करते हैं।

एकाधिक वंशानुक्रम

एक उदाहरण जहां यह स्पष्ट नहीं है वह कई उत्तराधिकार का उपयोग कर रहा है:

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

चीजें अब काम नहीं करती हैं क्योंकि आप उनसे उम्मीद कर सकते हैं:

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

इसलिए, यदि objectआपके परीक्षण के objectरूप में इसका एक अलग सेट है , तो आपको अप्रत्याशित परिणाम मिल सकते हैं prototype। इस चर्चा के दायरे से बाहर इसके तरीके हैं।

constructorसंपत्ति के लिए अन्य उपयोग हैं, उनमें से कुछ दिलचस्प हैं, दूसरों को इतना नहीं; क्योंकि हम इस चर्चा के लिए प्रासंगिक नहीं हैं, इसलिए हम उन उपयोगों में तल्लीन नहीं करेंगे।

क्रॉस-फ़्रेम और क्रॉस-विंडो पर काम नहीं करेगा

.constructorजब आप विभिन्न windowवस्तुओं से आने वाली वस्तुओं की जांच करना चाहते हैं तो टाइप चेकिंग का उपयोग करना बंद कर देगा , यह कहना कि आइफ्रेम या पॉपअप विंडो। ऐसा इसलिए है क्योंकि constructorप्रत्येक `विंडो 'में प्रत्येक कोर प्रकार का एक अलग संस्करण है , अर्थात

iframe.contentWindow.Array === Array // false

instanceofऑपरेटर का उपयोग कर रहा है ...

instanceofऑपरेटर के परीक्षण के लिए एक साफ रास्ता है objectजैसे साथ ही प्रकार है, लेकिन अपने स्वयं के संभावित मुद्दों है, constructorसंपत्ति।

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

लेकिन instanceofशाब्दिक मूल्यों के लिए काम करने में विफल रहता है (क्योंकि शाब्दिक नहीं हैं Objects)

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

उदाहरण के लिए, काम Objectकरने के लिए शाब्दिक रूप से लिपटे जाने की आवश्यकता होती हैinstanceof

new Number(3) instanceof Number // true

.constructorजांच शाब्दिक के लिए ठीक काम करता है क्योंकि .विधि मंगलाचरण परोक्ष उनके संबंधित ऑब्जेक्ट प्रकार में शाब्दिक लपेटता

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

3 के लिए दो बिंदु क्यों? क्योंकि जावास्क्रिप्ट पहले बिंदु को दशमलव बिंदु के रूप में व्याख्या करता है;)

क्रॉस-फ़्रेम और क्रॉस-विंडो पर काम नहीं करेगा

instanceofconstructorसंपत्ति की जाँच के समान कारण के लिए भी, अलग-अलग विंडो में काम नहीं करेंगे ।


nameप्रॉपर्टी के इस्तेमाल से constructor...

कई मामलों में सभी पर काम नहीं करता है

फिर, ऊपर देखें; यह constructorपूरी तरह से गलत और पूरी तरह से गलत और बेकार है।

<IE9 में काम नहीं करता है

उपयोग करने myObjectInstance.constructor.nameसे आपको उपयोग constructorकिए गए फ़ंक्शन के नाम से युक्त एक स्ट्रिंग मिलेगी , लेकिन constructorपहले बताई गई संपत्ति के बारे में चेतावनी के अधीन है ।

IE9 और इसके बाद के संस्करण के लिए, आप समर्थन में बंदर-पैच कर सकते हैं :

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

प्रश्न में लेख से अपडेट किया गया संस्करण । यह लेख प्रकाशित होने के 3 महीने बाद जोड़ा गया था, यह लेख के लेखक मैथ्यू शार्ले द्वारा उपयोग करने के लिए अनुशंसित संस्करण है। यह परिवर्तन पिछले कोड में संभावित नुकसान की ओर इशारा करते हुए टिप्पणियों से प्रेरित था ।

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
}

Object.prototype.toString का उपयोग करना

यह पता चला है, इस पोस्ट विवरण के रूप में , आप Object.prototype.toStringसभी निम्न toStringप्रकार के प्रकार प्राप्त करने के लिए - निम्न स्तर और सामान्य कार्यान्वयन का उपयोग कर सकते हैं

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

कोई भी इस तरह के एक छोटे सहायक समारोह लिख सकता है

function type(obj){
    return Object.prototype.toString.call(obj).slice(8, -1);
}

cruft को हटाने के लिए और बस नाम टाइप करें

type('abc') // String

हालांकि, यह Objectसभी उपयोगकर्ता-परिभाषित प्रकारों के लिए वापस आ जाएगा ।


सभी के लिए सहवास ...

ये सभी एक संभावित समस्या के अधीन हैं, और यह सवाल है कि प्रश्न में वस्तु का निर्माण कैसे किया गया था। यहाँ वस्तुओं के निर्माण के विभिन्न तरीके और मान हैं कि जाँच के विभिन्न तरीके वापस आएंगे:

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

जबकि इस क्रम के उदाहरणों में सभी क्रमपरिवर्तन मौजूद नहीं हैं, उम्मीद है कि आपको इस बारे में एक विचार प्रदान करने के लिए पर्याप्त है कि आपकी ज़रूरतों के आधार पर कैसे गड़बड़ चीजें मिल सकती हैं। कुछ भी मत मानो, अगर तुम ठीक से समझ नहीं पा रहे हो कि तुम क्या हो, तो तुम कोड तोड़ने के साथ समाप्त हो सकते हो, जहाँ तुम अपेक्षा नहीं करते हो क्योंकि यह सूक्ष्मता को टटोलने की कमी के कारण है।

ध्यान दें:

typeofऑपरेटर की चर्चा एक शानदार चूक हो सकती है, लेकिन यह वास्तव में यह पहचानने में मदद करने के लिए उपयोगी नहीं है कि क्या objectयह एक दिया हुआ प्रकार है, क्योंकि यह बहुत सरल है। यह समझना कि typeofउपयोगी कहाँ है, महत्वपूर्ण है, लेकिन मुझे वर्तमान में ऐसा नहीं लगता कि यह इस चर्चा के लिए बहुत प्रासंगिक है। मेरा मन हालांकि बदलने के लिए खुला है। :)


58
ठीक है, मुझे लगा कि मैं भी हो सकता हूं - स्टैक ओवरफ्लो का मुद्दा विकी की तरह एक सा होना है, और यह उस इरादे के अनुरूप बहुत अधिक है, मुझे लगता है। बावजूद, मैं बस कुछ हद तक पूरी तरह से बनना चाहता था।
जेसन बंटिंग

नीचे एक उत्तर को पुन: प्रसारित करना --- ऑब्जेक्ट प्रोटोटाइप के लिए आपका एक्सटेंशन IE8 में काम नहीं करता है - क्या किसी को पता है कि IE8 में क्या काम करेगा?
एडम

5
यदि आप इसे इस फंक्शन की तरह करते हैं तो यह काम करेगा (a) {this.a = 1;} function b () {this.b = 2; } b.prototype = new a (); // b विरासत में एक b.prototyp.constructor = b; // प्रोटोटाइपिक वंशानुक्रम var f = new b () का सही तरीका; // b कंस्ट्रक्टर (f.constructor == b) के साथ नई वस्तु बनाएं; // TRUE (f.constructor == a); // FALSE
बोरिस हमानोव

9
अब, यह है कि स्टैकऑवरफ्लो पर अधिकांश उत्तर कैसे होने चाहिए। (एक परिभाषित पैरामीटर के रूप में उत्तर की लंबाई न लें, लेकिन व्यापकता)
कुमारहर्ष

44
ऐसा नहीं है कि किसी भी तकनीक है कि वस्तु के निरीक्षण ध्यान देना महत्वपूर्ण है constructorविधि (या तो साथ .toString()या .nameअगर आपके जावास्क्रिप्ट बदसूरत करना जैसे उपकरण, या रेल संपत्ति पाइप लाइन के साथ न्यूनतम किया गया है) काम करने के लिए असफल हो जायेगी। निर्माणकर्ता का नाम बदल जाता है, इसलिए आप गलत श्रेणी के नामों को समाप्त कर देंगे n। आप इस परिदृश्य में हैं, तो आप सिर्फ कर सकते हैं मैन्युअल रूप से एक को परिभाषित classNameअपने वस्तुओं पर संपत्ति इसके बजाय उसका उपयोग।
गाबे मार्टिन-डेमस्पी

126

जेसन बंटिंग के जवाब ने मुझे एक सुराग दिया कि मुझे क्या चाहिए:

<<Object instance>>.constructor.name

इसलिए, उदाहरण के लिए, कोड के निम्नलिखित टुकड़े में:

function MyObject() {}
var myInstance = new MyObject();

myInstance.constructor.nameलौट आएंगे "MyObject"


22
पूर्णता के लिए, यह उल्लेख के लायक हो सकता है कि constructor.name का उपयोग केवल तभी काम करता है जब आपने एक नामित फ़ंक्शन का उपयोग एक अनाम फ़ंक्शन के विपरीत एक चर को सौंपा।
मैथ्यू क्रुमले

20
पूर्णता के लिए, यह उल्लेखनीय है कि यह IE ब्राउज़रों में काम नहीं करता है --- वे कार्यों पर "नाम" विशेषता का समर्थन नहीं करते हैं।
यूजीन लैजुटकिन 3

2
@ यूजीन - मैं इसके बारे में भूल गया ... मुझे लगता है कि मैंने बहुत समय ब्राउज़र के बाहर जावास्क्रिप्ट करने में बिताया है।
मैथ्यू क्रुमले

2
function getType(o) { return o && o.constructor && o.constructor.name }
justin.m.chase

यह SO व्यापक है।
ibबीक

26

एक छोटी सी चाल मैं उपयोग:

function Square(){
    this.className = "Square";
    this.corners = 4;
}

var MySquare = new Square();
console.log(MySquare.className); // "Square"

11
मुझे यह विशेष रूप से पसंद नहीं है। यह एक तरह की गंदी चाल है। दूसरी ओर, यदि आपके पास बहुत सारे निर्माता नहीं हैं, तो यह ठीक काम कर सकता है।
पिमवेदब

13
@pimvdb: मुझे लगता है कि यह ऑब्जेक्ट के प्रोटोटाइप को संशोधित करने की तुलना में क्लीनर है, एक स्वीकृत उत्तर है।
डैनियल ज़ैबाओ

4
@DanielSzabo अगर किसी संपत्ति में एक प्रोटोटाइप के सभी उदाहरणों के बीच समान मूल्य होना चाहिए, तो मैं निश्चित रूप से इसे केवल प्रोटोटाइप पर रखना पसंद करता हूं - प्रत्येक उदाहरण पर डाल देना अतिरेक है और मेटाडेटा स्वयं प्रोटोटाइप से गायब है। उस ने कहा, ईएस 6 में सबसे बुद्धिमान समाधान अपनाया गया था: यदि आपके पास class Square, नाम है Square.name/ MySquare.constructor.nameबजाय Square.prototype.name; nameकंस्ट्रक्टर फ़ंक्शन पर डालने से यह प्रोटोटाइप या किसी भी उदाहरण को प्रदूषित नहीं करता है, लेकिन दोनों में से सुलभ है।
एंडी

17

अपडेट करें

सटीक होने के लिए, मुझे लगता है कि ओपी ने एक फ़ंक्शन के लिए कहा जो किसी विशेष ऑब्जेक्ट के लिए निर्माता का नाम पुनर्प्राप्त करता है। जावास्क्रिप्ट के संदर्भ में, objectएक प्रकार नहीं है , लेकिन अपने आप में और एक प्रकार है । हालांकि, विभिन्न वस्तुओं में अलग-अलग निर्माता हो सकते हैं ।

Object.prototype.getConstructorName = function () {
   var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
   var cname = str.match(/function\s(\w*)/)[1];
   var aliases = ["", "anonymous", "Anonymous"];
   return aliases.indexOf(cname) > -1 ? "Function" : cname;
}

new Array().getConstructorName();  // returns "Array"
(function () {})().getConstructorName(); // returns "Function"

 


नोट: नीचे दिए गए उदाहरण को पदावनत किया गया है।

ईसाई Sciberras द्वारा लिंक किए गए एक ब्लॉग पोस्ट में यह कैसे करना है पर एक अच्छा उदाहरण है। अर्थात्, वस्तु प्रोटोटाइप का विस्तार करके:

if (!Object.prototype.getClassName) {
    Object.prototype.getClassName = function () {
        return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
    }
}

var test = [1,2,3,4,5];

alert(test.getClassName()); // returns Array

2
अच्छा है, लेकिन हम फिर से नामकरण में हैं: जेएस ने कक्षाएं नहीं ली हैं।
मिकमेकाना

@ नाविक - मैं अपडेट किए गए फ़ंक्शन का उपयोग करने की सलाह देता हूं, पुराने को केवल ऐतिहासिक कारणों से रखा गया है।
शाऊल

यह काम करता है लेकिन यह ध्यान दिया जाना चाहिए कि यह ऑब्जेक्ट को संशोधित किए बिना किया जा सकता है। एक फ़ंक्शन बनाकर, जो ऑब्जेक्ट को पहले तर्क के रूप में लेता है और फ़ंक्शन के अंदर 'इस' के बजाय इसका उपयोग करता है।
मैट ब्राउन

2
@ मट्टा - ज़रूर। यह सिर्फ इतना है कि एक वस्तु विधि अधिक है: test.getClassName()बनाम getClassName.apply(test)
शाऊल

12

Object.prototype.toString का उपयोग करना

यह पता चला है, इस पोस्ट विवरण के रूप में, आप ऑब्जेक्ट का उपयोग कर सकते हैं।

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

कोई भी इस तरह के एक छोटे सहायक समारोह लिख सकता है

function type(obj){
    return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}

return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function

6
आपको ऑब्जेक्ट नाम को पार्स करने के लिए रेगेक्स का उपयोग करने की आवश्यकता नहीं है। बस उपयोग करें .slice():Object.prototype.toString.call(obj).slice( 8, -1 );
bobobobo

9

यहाँ एक समाधान है कि मैं के साथ आया हूँ कि instof की कमियों को हल करता है। यह क्रॉस-विंडो और क्रॉस-फ़्रेम से ऑब्जेक्ट के प्रकारों की जांच कर सकता है और इसमें आदिम प्रकार की समस्याएं नहीं हैं।

function getType(o) {
    return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
    var ret = false,
    isTypeAString = getType(type) == "String",
    functionConstructor, i, l, typeArray, context;
    if (!isTypeAString && getType(type) != "Function") {
        throw new TypeError("type argument must be a string or function");
    }
    if (obj !== undefined && obj !== null && obj.constructor) {
        //get the Function constructor
        functionConstructor = obj.constructor;
        while (functionConstructor != functionConstructor.constructor) {
            functionConstructor = functionConstructor.constructor;
        }
        //get the object's window
        context = functionConstructor == Function ? self : functionConstructor("return window")();
        //get the constructor for the type
        if (isTypeAString) {
            //type is a string so we'll build the context (window.Array or window.some.Type)
            for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
                context = context[typeArray[i]];
            }
        } else {
            //type is a function so execute the function passing in the object's window
            //the return should be a constructor
            context = type(context);
        }
        //check if the object is an instance of the constructor
        if (context) {
            ret = obj instanceof context;
            if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
                ret = obj.constructor == context
            }
        }
    }
    return ret;
}

Isstance को दो मापदंडों की आवश्यकता होती है: एक ऑब्जेक्ट और एक प्रकार। यह कैसे काम करता है इसकी वास्तविक चाल यह है कि यह जाँचता है कि क्या वस्तु एक ही खिड़की से है और यदि वस्तु खिड़की से नहीं मिलती है।

उदाहरण:

isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true

function Animal() {}
function Dog() {}
Dog.prototype = new Animal();

isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false

प्रकार तर्क एक कॉलबैक फ़ंक्शन भी हो सकता है जो एक निर्माता को लौटाता है। कॉलबैक फ़ंक्शन को एक पैरामीटर मिलेगा जो प्रदान की गई ऑब्जेक्ट की विंडो है।

उदाहरण:

//"Arguments" type check
var args = (function() {
    return arguments;
}());

isInstance(args, function(w) {
    return w.Function("return arguments.constructor")();
}); //true

//"NodeList" type check
var nl = document.getElementsByTagName("*");

isInstance(nl, function(w) {
    return w.document.getElementsByTagName("bs").constructor;
}); //true

एक बात का ध्यान रखें कि IE <9 सभी ऑब्जेक्ट्स पर कंस्ट्रक्टर प्रदान नहीं करता है इसलिए NodeList के लिए उपरोक्त परीक्षण गलत वापस आ जाएगा और यह भी एक आईनेस्टेंस (चेतावनी, "फ़ंक्शन") गलत वापस आ जाएगी।


8

मैं वास्तव में इसी तरह की चीज की तलाश में था और इस सवाल पर आया था। यहाँ बताया गया है कि मैं किस प्रकार मिलता हूं: jsfiddle

var TypeOf = function ( thing ) {

    var typeOfThing = typeof thing;

    if ( 'object' === typeOfThing ) {

        typeOfThing = Object.prototype.toString.call( thing );

        if ( '[object Object]' === typeOfThing ) {

            if ( thing.constructor.name ) {
                return thing.constructor.name;
            } 

            else if ( '[' === thing.constructor.toString().charAt(0) ) {
                typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
            } 

            else {

                typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );

                if ( typeOfThing ) { 
                    return typeOfThing[1];
                } 

                else {
                    return 'Function';
                }
            }
        } 

        else {
            typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
        }
    }

    return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}

7

आपको इसका उपयोग करना चाहिए somevar.constructor.name:

    
    const getVariableType = a => a.constructor.name.toLowerCase();

    const d = new Date();
    const res1 = getVariableType(d); // 'date'
    const num = 5;
    const res2 = getVariableType(num); // 'number'
    const fn = () => {};
    const res3 = getVariableType(fn); // 'function'

    console.log(res1); // 'date'
    console.log(res2); // 'number'
    console.log(res3); // 'function'


6

constructor.nameजब आप कर सकते हैं, और जब मैं नहीं कर सकता तब regex फ़ंक्शन का उपयोग करें ।

Function.prototype.getName = function(){
  if (typeof this.name != 'undefined')
    return this.name;
  else
    return /function (.+)\(/.exec(this.toString())[1];
};

6

तरह () से समारोह Agave.JS वापस आ जाएगी:

  • वंशानुक्रम वृक्ष में निकटतम प्रोटोटाइप
  • हमेशा-आदिम प्रकार जैसे 'अशक्त' और 'अपरिभाषित' के लिए, आदिम नाम।

यह सभी जेएस ऑब्जेक्ट्स और प्राइमेटिव्स पर काम करता है, भले ही वे कैसे बनाए गए थे , और इसमें कोई आश्चर्य नहीं है। उदाहरण:

नंबर

kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'

NaN

kind(NaN) === 'NaN'

स्ट्रिंग्स

kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'

बूलियन्स

kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'

Arrays

kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'

वस्तुओं

kind({a:1}) === 'Object'
kind(new Object()) === 'Object'

खजूर

kind(new Date()) === 'Date'

कार्य

kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'

अपरिभाषित

kind(undefined) === 'undefined'

शून्य

kind(null) === 'null'

5

आप instanceofऑपरेटर का उपयोग यह देखने के लिए कर सकते हैं कि क्या कोई वस्तु दूसरे का उदाहरण है, लेकिन चूंकि कोई वर्ग नहीं है, इसलिए आपको कक्षा का नाम नहीं मिल सकता है।


हालांकि यह सच है कि जावास्क्रिप्ट में भाषा के निर्माण के रूप में कक्षाएं नहीं हैं, सामान्य सम्मेलन अभी भी है कि एक प्रकार की वस्तु को एक वर्ग कहा जाता है ..
शाऊल

2
@ स्पष्ट ज़रूर है लेकिन instanceofसिर्फ यह जाँचता है कि कोई वस्तु अन्य वस्तुओं से विरासत में मिली है या नहीं। जैसे, []ऐरे से एक साधारण विरासत, लेकिन ऐरे भी वस्तु से विरासत में मिली। चूंकि अधिकांश वस्तुओं में विरासत के कई स्तर होते हैं, इसलिए निकटतम प्रोटोटाइप को ढूंढना एक बेहतर तकनीक है। कैसे के लिए मेरा जवाब देखें।
मिकमेकाना

4

यहाँ एक जवाब के आधार पर कार्यान्वयन है :

/**
 * Returns the name of an object's type.
 *
 * If the input is undefined, returns "Undefined".
 * If the input is null, returns "Null".
 * If the input is a boolean, returns "Boolean".
 * If the input is a number, returns "Number".
 * If the input is a string, returns "String".
 * If the input is a named function or a class constructor, returns "Function".
 * If the input is an anonymous function, returns "AnonymousFunction".
 * If the input is an arrow function, returns "ArrowFunction".
 * If the input is a class instance, returns "Object".
 *
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @see <a href="https://stackoverflow.com/a/332429/14731">https://stackoverflow.com/a/332429/14731</a>
 * @see getFunctionName
 * @see getObjectClass 
 */
function getTypeName(object)
{
  const objectToString = Object.prototype.toString.call(object).slice(8, -1);
  if (objectToString === "Function")
  {
    const instanceToString = object.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "ArrowFunction";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
      return "AnonymousFunction";
    return "Function";
  }
  // Built-in types (e.g. String) or class instances
  return objectToString;
};

/**
 * Returns the name of a function.
 *
 * If the input is an anonymous function, returns "".
 * If the input is an arrow function, returns "=>".
 *
 * @param {Function} fn a function
 * @return {String} the name of the function
 * @throws {TypeError} if {@code fn} is not a function
 * @see getTypeName
 */
function getFunctionName(fn)
{
  try
  {
    const instanceToString = fn.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "=>";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
    {
      const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
      if (objectToString === "Function")
        return "";
      throw TypeError("object must be a Function.\n" +
        "Actual: " + getTypeName(fn));
    }
    return match[1];
  }
  catch (e)
  {
    throw TypeError("object must be a Function.\n" +
      "Actual: " + getTypeName(fn));
  }
};

/**
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @throws {TypeError} if {@code object} is not an Object
 * @see getTypeName
 */
function getObjectClass(object)
{
  const getFunctionName = /^function ([^(]+)\(/;
  const result = object.constructor.toString().match(getFunctionName)[1];
  if (result === "Function")
  {
    throw TypeError("object must be an Object.\n" +
      "Actual: " + getTypeName(object));
  }
  return result;
};


function UserFunction()
{
}

function UserClass()
{
}

let anonymousFunction = function()
{
};

let arrowFunction = i => i + 1;

console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(\"text\"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));

हम केवल कंस्ट्रक्टर संपत्ति का उपयोग करते हैं जब हमारे पास कोई अन्य विकल्प नहीं होता है।


3

आप "Instof" ऑपरेटर का उपयोग यह निर्धारित करने के लिए कर सकते हैं कि कोई ऑब्जेक्ट किसी निश्चित वर्ग का उदाहरण है या नहीं। यदि आपको किसी ऑब्जेक्ट के प्रकार का नाम नहीं पता है, तो आप इसकी कंस्ट्रक्टर प्रॉपर्टी का उपयोग कर सकते हैं। ऑब्जेक्ट्स की कंस्ट्रक्टर प्रॉपर्टी, उस फ़ंक्शन का एक संदर्भ है जिसका उपयोग उन्हें आरंभ करने के लिए किया जाता है। उदाहरण:

function Circle (x,y,radius) {
    this._x = x;
    this._y = y;
    this._radius = raduius;
}
var c1 = new Circle(10,20,5);

अब c1.constructor फ़ंक्शन का संदर्भ है Circle()। आप typeofऑपरेटर का उपयोग कर सकते हैं , लेकिन typeofऑपरेटर सीमित जानकारी दिखाता है। एक समाधान toString()ऑब्जेक्ट ग्लोबल ऑब्जेक्ट की विधि का उपयोग करना है । उदाहरण के लिए यदि आपके पास कोई ऑब्जेक्ट है, तो myObject कहें, आप myObject toString()के वर्ग के प्रकार को निर्धारित करने के लिए वैश्विक ऑब्जेक्ट की विधि का उपयोग कर सकते हैं । इसे इस्तेमाल करो:

Object.prototype.toString.apply(myObject);

3

बोलो तुम्हारे पास है var obj;

यदि आप ओब्ज के प्रकार का नाम चाहते हैं, जैसे "ऑब्जेक्ट", "एरे", या "स्ट्रिंग", तो आप इसका उपयोग कर सकते हैं:

Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');

2

निकटतम आप प्राप्त कर सकते हैं typeof, लेकिन यह किसी भी प्रकार के कस्टम प्रकार के लिए केवल "ऑब्जेक्ट" देता है। उन लोगों के लिए, जेसन बंटिंग देखें ।

संपादित करें, जेसन ने किसी कारण से अपना पद हटा दिया है, इसलिए बस ऑब्जेक्ट की constructorसंपत्ति का उपयोग करें ।


हाँ, क्षमा करें - मैंने इसे हटा दिया क्योंकि मुझे लगा कि इंफ़ॉफ़ () चीजों को करने का एक बेहतर तरीका है, लेकिन मैंने इसे अभी हटा दिया है ताकि यह एक संदर्भ के रूप में काम कर सके।
जेसन बंटिंग

2
सही उत्तर से कम अभी भी उपयोगी हैं, यदि केवल दूसरों को बाद में सवाल करने के लिए आना है क्योंकि उनके पास एक समान समस्या है। इसलिए आपको वास्तव में उन्हें हटाना नहीं चाहिए। गलत उत्तरों के लिए डिलीट सेव करें।
sblundy

2
हाँ, मुझे पता है - आप गाना बजानेवालों को उपदेश दे रहे हैं, मैंने दूसरों से भी यही बात कही है। उन चीज़ों को जीना जिन्हें हम जानते हैं कि यह सच है कि यह दिखने में अक्सर कठिन होती है। :)
जेसन बंटिंग

0

अगर किसी को एक समाधान की तलाश थी जो jQuery के साथ काम कर रहा है, तो यहां समायोजित विकी कोड (मूल ब्रेक jQuery) है।

Object.defineProperty(Object.prototype, "getClassName", {
    value: function() {
        var funcNameRegex = /function (.{1,})\(/;
        var results = (funcNameRegex).exec((this).constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    }
});

हाँ, jQuery एक 'hasOwnProperty' जांच करने में विफल रहता है और इसलिए आगे बढ़ता है getNameऔर गिर जाता है।
निकोडेमस 13

0

लोदाश के पास कई मैथोड हैं इसलिए यदि आप लोदश का उपयोग कर रहे हैं तो शायद इस तरह का मिश्रण उपयोगी हो सकता है:

  // Mixin for identifying a Javascript Object

  _.mixin({
      'identify' : function(object) {
        var output;
          var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments', 
              'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber', 
              'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']

          this.each(isMethods, function (method) {
              if (this[method](object)) {
                output = method;
                return false;
              }
          }.bind(this));
      return output;
      }
  });

यह "आइडेंट" कहे जाने वाले एक तरीके को जोड़ता है जो निम्न प्रकार से काम करता है:

console.log(_.identify('hello friend'));       // isString

प्लंकर: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN


0

ठीक है, दोस्तों मैं धीरे-धीरे कुछ वर्षों से इस के लिए एक पूरी विधि पकड़ रहा हूँ! चाल है:

  1. कक्षाएं बनाने के लिए एक तंत्र है।
  2. देशी कंस्ट्रक्टरों द्वारा निर्मित / उत्पन्न सभी उपयोगकर्ता, कक्षाओं, आदिम और मूल्यों की जांच के लिए एक तंत्र है।
  3. उपयोगकर्ता द्वारा बनाई गई कक्षाओं को नए में विस्तारित करने के लिए एक तंत्र है ताकि आपके कोड / एप्लिकेशन / लाइब्रेरी / आदि के माध्यम से उपरोक्त कार्यक्षमता की अनुमति हो।

उदाहरण के लिए (या यह देखने के लिए कि मैंने समस्या से कैसे निपटा है) निम्नलिखित कोड को github पर देखें : https://github.com/elycruz/sjljs/blob/master/src/sjl/sjll.js और खोजें:

classOf =, classOfIs =और defineSubClass =( या बैकटिक्स (`) के बिना)।

जैसा कि आप देख सकते हैं कि मेरे पास कुछ तंत्र हैं जो classOfमुझे हमेशा क्लास / कंस्ट्रक्टर्स टाइप नाम देने के लिए बाध्य करते हैं चाहे वह एक आदिम हो, एक उपयोगकर्ता परिभाषित वर्ग हो, एक देशी कंस्ट्रक्टर, नल, NaN, आदि का उपयोग करके बनाया गया मान। हर एक जावास्क्रिप्ट मूल्य के लिए, मुझे यह classOfफ़ंक्शन से अद्वितीय प्रकार का नाम मिलेगा । इसके अलावा, मैं वास्तविक कंस्ट्रक्टर में पास कर सकता हूं, sjl.classOfIsसाथ ही साथ यह टाइप नाम में पास होने के लिए एक मूल्य के प्रकार की जांच कर सकता है! उदाहरण के लिए:

`` `// कृपया लंबे नाम स्थान क्षमा करें! मुझे थोड़ी देर तक इस्तेमाल करने के बाद तक प्रभाव का कोई अंदाजा नहीं था (वे हाहा चूसते हैं)

var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
    constructor: function SomeCustomClass () {},
    // ...
}),

HelloIterator = sjl.ns.stdlib.Iterator.extend( 
    function HelloIterator () {}, 
    { /* ... methods here ... */ },
    { /* ... static props/methods here ... */ }
),

helloIt = new HelloIterator();

sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`

var someString = 'helloworld';

sjl.classOfIs(someString, String) === true; // `true`

sjl.classOfIs(99, Number) === true; // true

sjl.classOf(NaN) === 'NaN'; // true

sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`

// etc..

// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!

`` `

यदि आप इस बारे में अधिक पढ़ने में रुचि रखते हैं कि मैं ऊपर बताए गए सेटअप का उपयोग कैसे करता हूं, तो रेपो पर एक नज़र डालें: https://github.com/elycruz/sjljs

विषय पर सामग्री के साथ पुस्तकें भी: - स्टोअन स्टेफानोव द्वारा "जावास्क्रिप्ट पैटर्न"। - "जावास्क्रिप्ट - निश्चित गाइड।" डेविड फलागन द्वारा। - और कई अन्य .. (खोज ले` वेब)।

इसके अलावा, आप उन विशेषताओं का परीक्षण कर सकते हैं, जिनके बारे में मैं यहां बता रहा हूं: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (url में 0.5.18 पथ में भी github के स्रोत हैं वहाँ पर net_modules और ऐसे घटाएं)।

हैप्पी कोडिंग!


0

काफी सरल!

  • जेएस में कुछ भी पाने के लिए मेरा पसंदीदा तरीका
function getType(entity){
    var x = Object.prototype.toString.call(entity)
    return x.split(" ")[1].split(']')[0].toLowerCase()
}
  • जेएस में किसी भी प्रकार की जांच करने के लिए मेरी पसंदीदा विधि
function checkType(entity, type){
    return getType(entity) === type
}

-1

का उपयोग करें class.name। यह भी साथ काम करता है function.name

class TestA {}
console.log(TestA.name); // "TestA"

function TestB() {}
console.log(TestB.name); // "TestB"

प्रश्न स्पष्ट रूप से कहता है classऔर उदाहरण के लिए नहीं।
क्यूवर्त्जेगी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.