कुछ शाब्दिकों के लिए इंफ़ॉफ़ क्यों झूठा लौटता है?


284
"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false

// the tests against Object really don't make sense

एरे शाब्दिक और वस्तु शाब्दिक मिलान ...

[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true

उनमें से सभी क्यों नहीं? या, वे सब क्यों नहीं ?
और, वे एक उदाहरण क्या हैं?

यह FF3, IE7, Opera और Chrome में समान है। तो, कम से कम यह सुसंगत है।


कुछ याद किया।

12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true

जवाबों:


424

जावास्क्रिप्ट के भीतर से बनाई गई वस्तुओं की तुलना में प्राइमिटिव एक अलग प्रकार का प्रकार है। से मोज़िला एपीआई डॉक्स :

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

मुझे कोड के साथ आदिम प्रकार के निर्माण का कोई तरीका नहीं मिल रहा है, शायद यह संभव नहीं है। शायद यही कारण है कि लोग typeof "foo" === "string"इसके बजाय उपयोग करते हैं instanceof

इस तरह से चीजों को याद रखने का एक आसान तरीका खुद से पूछ रहा है "मुझे आश्चर्य है कि क्या समझदार और सीखना आसान होगा"? जो भी जवाब हो, जावास्क्रिप्ट दूसरी बात करता है।


5
जावास्क्रिप्ट से नफरत करने के एक नए कारण के साथ हर दिन एक अच्छा दिन है। मुझे पता है कि यह लंबे समय से अतिदेय है लेकिन मैं आपको इस पोस्ट के लिए धन्यवाद देता हूं।
toniedzwiedz

57
आपकी शब्दावली गलत है। शब्द "शाब्दिक" एक रचनाकार का उपयोग किए बिना डेटा बनाने के लिए एक वाक्यविन्यास को संदर्भित करता है। यह परिणामी डेटा को संदर्भित नहीं करता है। शाब्दिक वाक्य रचना का उपयोग वस्तुओं और गैर-वस्तुओं दोनों को बनाने के लिए किया जा सकता है। सही शब्द "आदिम" है, जो गैर-ऑब्जेक्ट डेटा को संदर्भित करता है। कुछ आंकड़ों में आदिम और वस्तु दोनों प्रतिनिधित्व हैं। स्ट्रिंग उन प्रकार के डेटा में से एक है।
ग्रे स्टेट

14
FYI करें, आप शाब्दिक वाक्य रचना के बिना आदिम बना सकते हैं। (new String()).valueOf();
ग्रे अवस्था में

11
ध्यान दें कि typeof foo === 'string'पर्याप्त नहीं है: अक्षतंतु का उत्तर देखें।
ब्रायन लार्सन

1
अतिरिक्त, में typeof new String('')रिटर्न"object"
transang

105

मैं उपयोग करता हूं:

function isString(s) {
    return typeof(s) === 'string' || s instanceof String;
}

क्योंकि जावास्क्रिप्ट में स्ट्रिंग शाब्दिक या ऑब्जेक्ट हो सकते हैं।


28
मुझे कुछ छोटा-सा btw मिला। function isString(s) { return s.constructor === String; }शाब्दिक और स्ट्रिंग ऑब्जेक्ट्स के लिए काम करता है (कम से कम V8 में)
axkibe

7
होगा प्यार जावास्क्रिप्ट।
डेरेक 會 會

2
मैं jQuery.type (s) === 'string' ( api.jquery.com/jquery.type ), jQuery.isArray (), jQuery.isFunction (), jQuery.isNumeric () का उपयोग करता हूं जब यह संभव है।
इवान सैमजिन

1
@axkibe जब आप सही होते हैं, तो यह लगभग उतना अच्छा नहीं होता जितना कि typeof
Qix - मोनासा ने 23

आप टाइपोफ़ का उपयोग कर सकते हैं "?" == String.name.toLowerCase () [लेकिन क्यों []
Instof

62

जावास्क्रिप्ट में, सब कुछ एक वस्तु है (या कम से कम एक वस्तु के रूप में माना जा सकता है), आदिम (बूलियन, अशक्त, संख्या, तार और मूल्य undefined(और ES6 में प्रतीक ) को छोड़कर ):

console.log(typeof true);           // boolean
console.log(typeof 0);              // number
console.log(typeof "");             // string
console.log(typeof undefined);      // undefined
console.log(typeof null);           // object
console.log(typeof []);             // object
console.log(typeof {});             // object
console.log(typeof function () {}); // function

जैसा कि आप वस्तुओं, सरणियों और मूल्य nullको देख सकते हैं सभी वस्तुओं को माना जाता है ( nullयह एक वस्तु का संदर्भ है जो मौजूद नहीं है)। फ़ंक्शंस प्रतिष्ठित हैं क्योंकि वे एक विशेष प्रकार की कॉल करने योग्य वस्तु हैं। हालाँकि वे अभी भी वस्तुएं हैं।

दूसरी ओर शाब्दिक true, 0, ""और undefinedनहीं वस्तुओं रहे हैं। वे जावास्क्रिप्ट में आदिम मूल्य हैं। हालाँकि, बूलियन्स, संख्याओं और तारों में भी कंस्ट्रक्टर होते हैं Boolean, Numberऔर Stringक्रमशः जो जोड़ा कार्यक्षमता प्रदान करने के लिए अपने संबंधित प्राइमेटिक्स को लपेटते हैं:

console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0));     // object
console.log(typeof new String(""));    // object

जैसा कि आप देख सकते हैं कि जब आदिम मूल्य वस्तुओं के भीतर लपेटे जाते हैं Boolean, Numberऔर Stringनिर्माणकर्ता क्रमशः ऑब्जेक्ट बन जाते हैं। instanceofऑपरेटर केवल वस्तुओं के लिए काम करता है (यही कारण है कि रिटर्न falseआदिम मूल्यों के लिए):

console.log(true instanceof Boolean);              // false
console.log(0 instanceof Number);                  // false
console.log("" instanceof String);                 // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number);      // true
console.log(new String("") instanceof String);     // true

जैसा कि आप दोनों देख सकते हैं typeofऔर instanceofयह जांचने के लिए अपर्याप्त हैं कि क्या एक बूलियन, एक संख्या या एक स्ट्रिंग है - typeofकेवल आदिम बूलियन , संख्या और तारों के लिए काम करता है; और instanceofआदिम बूलियन, संख्या और तारों के लिए काम नहीं करता है।

सौभाग्य से इस समस्या का एक सरल समाधान है। का डिफ़ॉल्ट कार्यान्वयन toString(अर्थात जैसा कि यह मूल रूप से परिभाषित किया गया है Object.prototype.toString) [[Class]]आदिम मूल्यों और वस्तुओं दोनों की आंतरिक संपत्ति लौटाता है :

function classOf(value) {
    return Object.prototype.toString.call(value);
}

console.log(classOf(true));              // [object Boolean]
console.log(classOf(0));                 // [object Number]
console.log(classOf(""));                // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0)));     // [object Number]
console.log(classOf(new String("")));    // [object String]

[[Class]]मूल्य की आंतरिक संपत्ति मूल्य से बहुत अधिक उपयोगी है typeof। हम ऑपरेटर के Object.prototype.toStringअपने स्वयं के (अधिक उपयोगी) संस्करण बनाने के लिए उपयोग कर सकते हैं typeof:

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

console.log(typeOf(true));              // Boolean
console.log(typeOf(0));                 // Number
console.log(typeOf(""));                // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0)));     // Number
console.log(typeOf(new String("")));    // String

आशा है कि इस लेख से मदद मिली। आदिम और लिपटी वस्तुओं के बीच के अंतर के बारे में अधिक जानने के लिए निम्नलिखित ब्लॉग पोस्ट पढ़ें: द सीक्रेट लाइफ ऑफ जावास्क्रिप्ट प्राइमेटीज


6
+1, nullपूरी तरह से एक आदिम मूल्य है (केवल typeofऑपरेटर भ्रामक है)
Bergi

33

आप कंस्ट्रक्टर संपत्ति का उपयोग कर सकते हैं:

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true

18
ध्यान दें कि जब चर परीक्षण करते हैं तो यह तकनीक कुछ परिस्थितियों में विफल हो सकती है। उपरोक्त विंडो में Stringऔर सामने Booleanउदाहरण में वर्तमान विंडो का एक अंतर्निहित संदर्भ है , इसलिए यदि आप constructorकिसी अन्य विंडो (जैसे पॉपअप या फ्रेम) में बनाए गए स्ट्रिंग चर की संपत्ति का परीक्षण कर रहे हैं तो यह बस के बराबर नहीं होगा String, यह होगा के बराबर हो thatOtherWindowsName.String
माइकल मैथ्यूज

और क्या इस से निपटने के लिए और उचित बूलियन परिणाम वापस नहीं आता है?
क्रिस नू

5
यदि आप स्ट्रिंग के वंशज हैं तो यह विफल हो जाता है।
ब्रायन लार्सन

1
@MichaelMathews: यह उपाय है कि काम करता है:Object.prototype.toString.call('foo') === '[object String]'
rvighne

@BryanLarsen और @MichaelMathews का उपयोग करने में कोई समस्या है d.constructor == String? जैसे एक ढीली समानता ऑपरेटर के साथ।
डॉटनेटकारपेंटर

7
 typeof(text) === 'string' || text instanceof String; 

आप इसका उपयोग कर सकते हैं, यह दोनों मामलों के लिए काम करेगा

  1. var text="foo"; // टाइपो काम करेगा

  2. String text= new String("foo"); // Instof काम करेगा


3

इसे ECMAScript विनिर्देश खंड 7.3.19 चरण 3 में परिभाषित किया गया है :If Type(O) is not Object, return false.

दूसरे शब्दों में, अगर Objमें Obj instanceof Callableएक वस्तु नहीं है, instanceofकरने के लिए शॉर्ट सर्किट होगा falseसीधे।


1

मुझे विश्वास है कि मैं एक व्यवहार्य समाधान के साथ आया हूँ:

Object.getPrototypeOf('test') === String.prototype    //true
Object.getPrototypeOf(1) === String.prototype         //false

-1

https://www.npmjs.com/package/typeof

instanceof(निर्माता नाम) का एक स्ट्रिंग-प्रतिनिधित्व लौटाता है

function instanceOf(object) {
  var type = typeof object

  if (type === 'undefined') {
    return 'undefined'
  }

  if (object) {
    type = object.constructor.name
  } else if (type === 'object') {
    type = Object.prototype.toString.call(object).slice(8, -1)
  }

  return type.toLowerCase()
}

instanceOf(false)                  // "boolean"
instanceOf(new Promise(() => {}))  // "promise"
instanceOf(null)                   // "null"
instanceOf(undefined)              // "undefined"
instanceOf(1)                      // "number"
instanceOf(() => {})               // "function"
instanceOf([])                     // "array"

-2

मेरे लिए भ्रम की वजह से

"str".__proto__ // #1
=> String

इसलिए "str" istanceof Stringलौटना चाहिए trueक्योंकि istanceof कैसे काम करता है:

"str".__proto__ == String.prototype // #2
=> true

अभिव्यक्ति के परिणाम # 1 और # 2 एक दूसरे से संघर्ष करते हैं, इसलिए उनमें से एक गलत होना चाहिए।

# 1 गलत है

मुझे पता है कि यह __proto__गैर मानक संपत्ति है, इसलिए मानक एक का उपयोग करें:Object.getPrototypeOf

Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object

अब अभिव्यक्ति # 2 और # 3 के बीच कोई भ्रम नहीं है


2
# 1 सही है, लेकिन यह संपत्ति के एक्सेसर के कारण है , जो अपने संबंधित ऑब्जेक्ट प्रकार के लिए आदिम मूल्य को बॉक्स के समान Object("str").__proto__या उसके समान करता है Object("str") instanceof String
जोनाथन लोनोव्स्की

@JonathanLonowski इस ओर इशारा करने के लिए धन्यवाद। मुझे नहीं पता था कि
mko

-8

या आप बस अपना खुद का फ़ंक्शन बना सकते हैं जैसे:

function isInstanceOf(obj, clazz){
  return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};

उपयोग:

isInstanceOf('','String');
isInstanceOf(new String(), 'String');

इन दोनों को वापस लौटना चाहिए।


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