जावास्क्रिप्ट चर के प्रकार प्राप्त करने का बेहतर तरीका है?


260

जेएस की तुलना में चर का प्रकार प्राप्त करने का एक बेहतर तरीका है typeof? यह ठीक काम करता है जब आप करते हैं:

> typeof 1
"number"
> typeof "hello"
"string"

लेकिन यह बेकार है जब आप कोशिश करते हैं:

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

मुझे पता है instanceof, लेकिन इसके लिए आपको पहले से इस प्रकार को जानना होगा।

> [1,2] instanceof Array
true
> r instanceof RegExp
true

क्या कोई बेहतर तरीका है?


1
FYI करें, typeof new RegExp(/./); // "function"Chrome में समस्या Chrome 14.
user113716


चेतावनी: यदि आप अपने JS को मिनिमाइज कर रहे हैं और आप 'कस्टम ऑब्जेक्ट्स' जैसे कि टाइपस्क्रिप्ट क्लास का उपयोग कर रहे हैं, तो नीचे दिए गए कुछ उत्तर आपको nमूल नाम के बजाय ओफ़्स्कुलेटेड फंक्शन नाम देंगे । उदाहरण के constructor.nameलिए आपको nपूरा नाम दिया जा सकता है
सिमोन_विवर

जवाबों:


221

एंगस क्रॉल ने हाल ही में इस बारे में एक दिलचस्प ब्लॉग पोस्ट लिखा है -

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

वह विभिन्न तरीकों के पेशेवरों और विपक्षों के माध्यम से जाता है, फिर एक नई विधि 'toType' को परिभाषित करता है -

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

3
यहां दिलचस्प पक्ष नोट - यह संभावित रूप से टूट सकता है जहां एक "होस्ट" ऑब्जेक्ट फ़ंक्शन को पास किया जाता है। ActiveXObjectउदाहरण के लिए, इंटरनेट एक्सप्लोरर उदाहरण।
एंडी ई।

यदि आपने अपना ऑब्जेक्ट प्रकार (प्रोटोटाइप इनहेरिटेंस) बनाया है, तो आपको "ऑब्जेक्ट" से अधिक विशिष्ट मूल्य वापस करने के लिए कैसे मिल सकता है? इसे यहां एक मुद्दे के रूप में भी उठाया गया था , लेकिन कभी संबोधित नहीं किया गया था।
इलेवनटाइन 19

1
यदि आपके प्रकार के नामकरण में यह शामिल है: या _ आप इस regex कोmatch(/\s([a-z,_,:,A-Z]+)/)
masi

6
रेगेक्स को भी जैसी चीजों के लिए नंबर शामिल करने होंगे Uint8Array। इसके बजाय, अधिक सामान्य पर विचार करें match(/\s([^\]]+)/)जो कुछ भी संभालना चाहिए।
लिली फिनाले

2
मैं \wइसके बजाय शब्द ऑपरेटर का उपयोग करने का सुझाव देता हूं ...
kaiser

51

आप प्रयोग करके देख सकते हैं constructor.name

[].constructor.name
new RegExp().constructor.name

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

एक विकल्प का उपयोग करना है Object.prototype.toString.call

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)

10
nameECMAScript का विस्तार है और सभी ब्राउज़रों में काम नहीं करेगा।
एंडी ई।

16
उत्तर-मतदान में संदेह की पुष्टि के कारण कि जावास्क्रिप्ट में किया गया सब कुछ किसी भी तरह से बुराई है।
लीलजोशू 22

1
EVIL: यदि आप अपने कोड को छोटा कर रहे हैं, तो constructor.nameसंभवतः nआपके द्वारा अपेक्षित ऑब्जेक्ट नाम के बजाय कुछ होने की संभावना हो सकती है। तो उस के लिए बाहर देखो - खासकर यदि आप केवल उत्पादन में छोटा करते हैं।
सिमोन_विवर

nullऔर undefinedदुर्भाग्य से एक निर्माता नहीं है।
एंड्रयू ग्रिम

जावास्क्रिप्ट ही बुराई है। और मूर्खतापूर्ण। यह तथ्य कि इस सवाल का कोई अच्छा जवाब नहीं है, इसका जीता जागता सबूत है।
user2173353

38

यथोचित प्रकार के कैप्चर फ़ंक्शन का उपयोग YUI3 द्वारा किया जाता है :

var TYPES = {
    'undefined'        : 'undefined',
    'number'           : 'number',
    'boolean'          : 'boolean',
    'string'           : 'string',
    '[object Function]': 'function',
    '[object RegExp]'  : 'regexp',
    '[object Array]'   : 'array',
    '[object Date]'    : 'date',
    '[object Error]'   : 'error'
},
TOSTRING = Object.prototype.toString;

function type(o) {
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};

यह जावास्क्रिप्ट द्वारा प्रदान की गई कई प्राथमिकताओं को कैप्चर करता है, लेकिन आप हमेशा TYPESऑब्जेक्ट को संशोधित करके अधिक जोड़ सकते हैं । ध्यान दें कि typeof HTMLElementCollectionसफारी में रिपोर्ट होगी function, लेकिन टाइप (HTMLElementCollection) वापस आ जाएगीobject


31

आपको निम्न फ़ंक्शन उपयोगी मिल सकता है:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

या ईएस 7 (टिप्पणी में और सुधार करें)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

परिणाम:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

धन्यवाद @johnrees की मुझे सूचित करने के लिए: त्रुटि, वादा, जनरेटरफंक्शन


इसके लिए धन्यवाद। यह दिनांक वस्तुओं के लिए भी काम करता है:typeOf(new Date())
जेम्स इरविन

आह, मैं इसके बारे में भूल गया था - धन्यवाद, यह अब शामिल है।
विक्स

1
औरtypeOf(Promise.resolve())//promise typeOf(function *() {})//generatorfunction
जॉन्ज

मुझे यह उत्तर टाइपस्क्रिप्ट में काम करने के लिए नहीं मिला। त्रुटि देता है:[ts] Cannot redeclare block-scoped variable 'toString'
DauleDK

टाइपस्क्रिप्ट के बारे में निश्चित नहीं है। क्या आपने ES7 संस्करण की कोशिश की है? स्पष्ट रूप से घोषित नहीं होने का कारण हो सकता है?
विक्स

15

इसके अलावा, हम ipr101 से थोड़ा सा उदाहरण बदल सकते हैं

Object.prototype.toType = function() {
  return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

और के रूप में बुलाओ

"aaa".toType(); // 'string'

6
बच्चों को याद रखें, जावास्क्रिप्ट बेस ऑब्जेक्ट्स में हेरफेर करने से संगतता और अन्य अजीब मुद्दे हो सकते हैं। पुस्तकालयों और बड़ी परियोजनाओं दोनों में इस संयम का उपयोग करने का प्रयास करें!
अलेक्जेंडर क्रैग्स

9

एक पंक्ति समारोह:

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

इस परिणाम के रूप में एक ही दे jQuery.type()


3

आप Object.prototype.toStringकिसी भी वस्तु पर आवेदन कर सकते हैं :

var toString = Object.prototype.toString;

console.log(toString.call([]));
//-> [object Array]

console.log(toString.call(/reg/g));
//-> [object RegExp]

console.log(toString.call({}));
//-> [object Object]

यह IE के अपवाद के साथ सभी ब्राउज़रों में अच्छी तरह से काम करता है - जब इसे किसी अन्य विंडो से प्राप्त चर पर कॉल किया जाता है तो यह बस बाहर थूक देगा [object Object]


1
@Xeon मुझे लगता है कि IE के खिलाफ नफरत थोड़ी बहुत है। IE9 अपने पूर्ववर्तियों की तुलना में बहुत बेहतर ब्राउज़र है।
ऐलिं स

4
@pessimopoppotamus लेकिन IE9 का उपयोग करने वाले अपने ब्राउज़र को अपडेट करने वाला कोई भी IE का उपयोग नहीं करता है।
एलेक्स टर्पिन

1
IE 9 सही दिशा में एक कदम है, IE 10 बहुत अच्छा लग रहा है। संयोग से, जिस बग का मैंने उल्लेख किया था वह IE 9 में एक प्रतिगमन था - उन्होंने इसे IE 8 में तय किया था
एंडी ई 1

3

मेरे 2 ¢! वास्तव में, इस कारण का हिस्सा मैं इसे यहां फेंक रहा हूं, उत्तर की लंबी सूची के बावजूद, थोड़ा और अधिक all in oneप्रकार का समाधान प्रदान करना है और भविष्य में कुछ फ़ीड वापस प्राप्त करना है कि इसे और अधिक कैसे शामिल किया जाए real types

निम्नलिखित समाधान के साथ, उपर्युक्त के रूप में, मैंने यहां पाए गए कुछ समाधानों को संयुक्त किया, साथ ही यदि उपलब्ध हो तो jQuery परिभाषित वस्तु पर एक मूल्य वापस करने के लिए एक निर्धारण शामिल करें । मैं मूल वस्तु प्रोटोटाइप के लिए विधि भी जोड़ता हूं। मुझे पता है कि यह अक्सर वर्जित है, क्योंकि यह ऐसे अन्य एक्सटेंशन के साथ हस्तक्षेप कर सकता है, लेकिन मैं इसे छोड़ देता हूं । यदि आपको ऐसा करने का यह तरीका पसंद नहीं है, तो बस आधार फ़ंक्शन को कहीं भी कॉपी करें और पास करने के लिए एक तर्क पैरामीटर के साथ सभी चर को बदलें (जैसे तर्क [0])।jQueryuser bewarethis

;(function() {  //  Object.realType
    function realType(toLower) {
        var r = typeof this;
        try {
            if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery';
            else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
        }
        catch(e) { if (this['toString']) r = this.toString().slice(8, -1); }
        return !toLower ? r : r.toLowerCase();
    }
    Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType')
        ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType;
})();

तो बस आराम से उपयोग करें, जैसे:

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'

नोट: 1 तर्क पास करने योग्य है। यदि बूल है true, तो वापसी हमेशा लोअरकेस में होगी ।

और ज्यादा उदाहरण:

true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"

यदि आपके पास ऐसा कुछ जोड़ने के लिए है जो शायद सहायक हो, जैसे कि किसी ऑब्जेक्ट को किसी अन्य लाइब्रेरी (Moo, Proto, Yui, Dojo, आदि ...) के साथ परिभाषित किया गया हो, तो कृपया इसे टिप्पणी या संपादित करने के लिए स्वतंत्र महसूस करें और इसे और अधिक जारी रखें सटीक और सटीक। या GitHubइसके लिए किए गए I से अधिक रोल करें और मुझे बताएं। आपको वहां cdn मिन फ़ाइल में एक त्वरित लिंक भी मिलेगा।


2
function getType(obj) {
    if(obj && obj.constructor && obj.constructor.name) {
        return obj.constructor.name;
    }
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

मेरे प्रारंभिक परीक्षणों में, यह बहुत अच्छा काम कर रहा है। पहला मामला "नया" के साथ बनाई गई किसी भी वस्तु का नाम प्रिंट करेगा, और दूसरा मामला बाकी सब को पकड़ना चाहिए।

मैं उपयोग (8, -1)कर रहा हूं क्योंकि मैं यह मान रहा हूं कि परिणाम हमेशा के साथ शुरू [objectऔर समाप्त होने वाला है ]लेकिन मुझे यकीन नहीं है कि यह हर परिदृश्य में सच है।


2

मुझे लगता है कि यहां सबसे सार्वभौमिक समाधान है - पहले undefinedऔर nullफिर जांच करने के लिए constructor.name.toLowerCase()

const getType = v =>
  v === undefined
    ? 'undefined'
    : v === null
      ? 'null'
      : v.constructor.name.toLowerCase();




console.log(getType(undefined)); // 'undefined'
console.log(getType(null)); // 'null'
console.log(getType('')); // 'string'
console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(new Set())); // `set'
console.log(getType(Promise.resolve())); // `promise'
console.log(getType(new Map())); // `map'

जहाँ तक मुझे पता है - .constructor.nameहमेशा स्ट्रिंग मान होता है। अपरिभाषित / अशक्त के लिए हमारे पास फ़ंक्शन द्वारा लौटाए गए उपयुक्त तार हैं।
आर्सेनोविच

धन्यवाद - मेरी टिप्पणियों को हटाने ...
Bergi

चूंकि constructorएक विरासत में मिली संपत्ति है, इस के साथ निर्मित वस्तुओं के लिए टूट जाता है Object.create(null)। ठीक करने के लिए पर्याप्त सरल है, लेकिन इसे कॉल करने के लिए क्या है? "[ऑब्जेक्ट अशक्त]"?
traktor53

0

typeof वेरिएबल टाइप को चेक करने के लिए कंडीशन का इस्तेमाल किया जाता है, यदि आप वेरिएबल टाइप को if-else कंडीशन में चेक करते हैं

if(typeof Varaible_Name "undefined")
{

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