टाइपोफ़ और इंस्टोफ़ के बीच अंतर क्या है और कब एक का उपयोग दूसरे के बीच किया जाना चाहिए?


394

मेरे विशेष मामले में:

callback instanceof Function

या

typeof callback == "function"

क्या फर्क पड़ता है, क्या फर्क पड़ता है?

अतिरिक्त संसाधन:

जावास्क्रिप्ट-गार्डन typeof बनाम instanceof


2
मुझे अपना उत्तर यहाँ हल करने में आसान के रूप में मिला
CrandellWS

1
Object.prototype.toString Ecma-international.org/ecma-262/6.0/…
rab

1
.constructorइसके बजाय संपत्ति का उपयोग करें ।
मुहम्मद उमर

यदि आप प्रदर्शन के बारे में आश्चर्य करते हैं , तो नीचे मेरा उत्तर देखेंटाइपोफ़ तेज़ है जहाँ दोनों लागू होते हैं (अर्थात् वस्तुएँ)।
मार्टिन पीटर

जवाबों:


540

instanceofकस्टम प्रकारों के लिए उपयोग करें :

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

typeofसरल प्रकार में निर्मित के लिए उपयोग करें :

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

instanceofप्रकार में निर्मित जटिल के लिए उपयोग करें :

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

और आखिरी एक छोटी सी मुश्किल है:

typeof null; // object

11
यह उत्तर स्पष्ट करता है कि आदिम प्रकारों के लिए इंस्टास्कोफ का उपयोग क्यों नहीं किया जाना चाहिए । यह स्पष्ट है कि आपके पास कोई विकल्प नहीं है जब यह कस्टम प्रकारों के साथ-साथ 'ऑब्जेक्ट' प्रकारों के लिए लाभ होता है। लेकिन क्या कार्य "सरल अंतर्निर्मित प्रकारों" से प्रभावित होता है? मुझे यह अजीब लगता है कि कोई फ़ंक्शन किसी ऑब्जेक्ट की तरह कैसे व्यवहार करता है, फिर भी यह टाइप 'फंक्शन' है जो 'टाइपोफ' के उपयोग को संभव बनाता है। हालांकि, आप इसके लिए उदाहरण क्यों हतोत्साहित करेंगे?
अस्मिलिटर

4
@Assimilater आप फ़ंक्शंस का उपयोग फ़ंक्शंस के साथ कर सकते हैं, लेकिन मैं इन 3 नियमों को याद रखना बहुत सरल मानता हूं और हां, फ़ंक्शंस एक अपवाद हैं :)
सिजेन वैगनैस्की

2
एक और पेचीदा हिस्सा -> 'उदाहरण स्ट्रिंग' इंस्टोफ़ स्ट्रिंग; // गलत लेकिन नया स्ट्रिंग ('उदाहरण स्ट्रिंग') उदाहरण स्ट्रिंग; // सच
ल्यूक

2
@ ल्यूक आमतौर पर इस तरह के "नए स्ट्रिंग" का उपयोग करने के लिए एक बुरा विचार है। जो एक स्ट्रिंग आदिम के बजाय "स्ट्रिंग ऑब्जेक्ट" बनाता है। यहाँ अनुभाग देखें। developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
कोलिन डी

4
Use instanceof for complex built in types- यह अभी भी त्रुटि का खतरा है। ES5 Array.isArray()एट अल का उपयोग करने के लिए बेहतर है । या अनुशंसित शिम।
ऑरेंजडॉग

122

दोनों कार्यक्षमता में समान हैं क्योंकि वे दोनों प्रकार की जानकारी लौटाते हैं, हालांकि मैं व्यक्तिगत रूप से पसंद करता हूं instanceofक्योंकि यह तार के बजाय वास्तविक प्रकारों की तुलना कर रहा है। टाइप तुलना मानव त्रुटि के लिए कम प्रवण है, और यह तकनीकी रूप से तेज है क्योंकि यह पूरे स्ट्रिंग तुलना करने के बजाय मेमोरी में पॉइंटर्स की तुलना कर रहा है।


8
ऐसी कुछ स्थितियाँ हैं, जहाँ
इंस्टॉफ़

55
Instof एक ही विंडो में ऑब्जेक्ट्स के साथ काम करता है। यदि आप iframe / फ्रेम या पॉपअप-विंडो का उपयोग करते हैं, तो प्रत्येक (i) फ्रेम / विंडो का अपना "फंक्शन" ऑब्जेक्ट होता है और यदि आप किसी ऑब्जेक्ट को दूसरे (i) फ्रेम / विंडो से तुलना करने का प्रयास करते हैं तो असफल हो जाएगा। टाइपोफ़ सभी मामलों में काम करेगा क्योंकि यह स्ट्रिंग "फ़ंक्शन" लौटाता है।
कुछ

14
jsperf.com/typeof-function-vs-instanceof/3 मैंने क्रोम और FF3.X पर कोशिश की, "टाइपोफ़" दृष्टिकोण अधिक तेज़ है।
मॉर्गन चेंग

10
यह सिर्फ झूठ है। वे समान नहीं हैं। वे दोनों समान परिस्थितियों में, विशेष रूप से विभिन्न जावास्क्रिप्ट वीएम और ब्राउज़रों में काम नहीं करते हैं।
जस्टिन फोर्स

8
आपका उत्तर कहता है "कार्यक्षमता के मामले में दोनों अनिवार्य रूप से समान हैं।" सम्मान से, यह गलत है। जैसा कि मेरे उत्तर में उल्लिखित और समझाया गया है, न तो विकल्प हर स्थिति में काम करता है - विशेष रूप से ब्राउज़रों में। दोनों के साथ उपयोग करने के लिए बेहतर तरीका है || ऑपरेटर।
जस्टिन फोर्स

103

टाइपोफ़ का उपयोग करने का एक अच्छा कारण यह है कि चर अपरिभाषित हो सकता है।

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

Instof का उपयोग करने का एक अच्छा कारण यह है कि चर शून्य हो सकता है।

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

तो वास्तव में मेरी राय में यह इस बात पर निर्भर करेगा कि आप किस प्रकार के संभावित डेटा की जाँच कर रहे हैं।


11
+1 यह भी ध्यान दें कि instanceofआदिम प्रकारों की तुलना नहीं की जा सकती है, टाइपोफ़ कर सकते हैं।
टीनो

3
Chrome में 29.0.1541.0 देव undefined instanceof Objectझूठे हैं, और अपवाद नहीं फेंकते हैं। मुझे नहीं पता कि वह हाल ही में कितना बदल गया है, लेकिन यह instanceofअधिक आकर्षक बनाता है ।
सरू फ्रैंकनफेल्ड

7
undefined instanceof Objectकोई अपवाद नहीं फेंकता है, क्योंकि, एह undefinedपरिभाषित किया गया है। नामस्थान में स्थिरांक विद्यमान है। जब एक चर मौजूद नहीं होता है (उदाहरण के लिए टाइपो के कारण), तो Instof एक अपवाद फेंक देगा। एक गैर-मौजूदा चर पैदावार पर टाइपोफ का उपयोग करना दूसरी ओर 'अपरिभाषित' है।
क्लोंग

31

चीजों को स्पष्ट करने के लिए, आपको दो तथ्यों को जानना होगा:

  1. Instanceof कि क्या ऑपरेटर परीक्षण प्रोटोटाइप संपत्ति एक के निर्माता में कहीं भी दिखाई देता है प्रोटोटाइप श्रृंखला एक वस्तु की। ज्यादातर मामलों में इसका मतलब यह है कि इस निर्माता या उसके वंशज का उपयोग करके ऑब्जेक्ट बनाया गया था । लेकिन प्रोटोटाइप को स्पष्ट रूप से Object.setPrototypeOf()विधि (ईसीएमएस्क्रिप्ट 2015) या __proto__संपत्ति (पुराने ब्राउज़रों, पदावनत) द्वारा सेट किया जा सकता है । प्रदर्शन के मुद्दों के कारण, किसी वस्तु के प्रोटोटाइप को बदलने की सिफारिश नहीं की जाती है।

इस प्रकार Instof केवल वस्तुओं पर लागू होता है। ज्यादातर मामलों में आप कंस्ट्रक्टर का उपयोग स्ट्रिंग्स या संख्या बनाने के लिए नहीं कर रहे हैं। आप ऐसा कर सकते हैं। लेकिन आप लगभग कभी नहीं करते।

उदाहरण के तौर पर यह नहीं जांचा जा सकता है कि वास्तव में किस कंस्ट्रक्टर का उपयोग ऑब्जेक्ट बनाने के लिए किया गया था, लेकिन यह सही होगा, भले ही वह ऑब्जेक्ट क्लास से लिया गया हो, जिसे चेक किया जा रहा हो। ज्यादातर मामलों में यह वांछित व्यवहार है, लेकिन कभी-कभी यह नहीं होता है। इसलिए आपको वह दिमाग रखने की जरूरत है।

एक और समस्या यह है कि अलग-अलग स्कोप में अलग-अलग निष्पादन का वातावरण होता है। इसका मतलब यह है कि उनके पास अलग-अलग बिल्ट-इन (अलग-अलग वैश्विक वस्तु, विभिन्न निर्माणकर्ता, आदि) हैं। इससे अप्रत्याशित परिणाम प्राप्त हो सकते हैं।

उदाहरण के लिए, [] instanceof window.frames[0].Arrayवापस आ जाएगा false, क्योंकि Array.prototype !== window.frames[0].Arrayऔर सरणियाँ पूर्व से विरासत में मिली हैं।
इसके अलावा, इसका उपयोग अपरिभाषित मूल्य पर नहीं किया जा सकता है, क्योंकि इसका कोई प्रोटोटाइप नहीं है।

  1. Typeof ऑपरेटर परीक्षण है कि क्या मूल्य से संबंधित छह बुनियादी प्रकारों में से एक : " संख्या ", " स्ट्रिंग ", " बूलियन ", " वस्तु ", " समारोह " या " अपरिभाषित "। जहाँ स्ट्रिंग "ऑब्जेक्ट" में सभी ऑब्जेक्ट्स होते हैं (फ़ंक्शंस को छोड़कर, जो ऑब्जेक्ट्स होते हैं, लेकिन टाइपोफ़ ऑपरेटर में इसका अपना मूल्य होता है), और "null" वैल्यू और एरेज़ ("null" के लिए यह एक बग है, लेकिन यह बग इतना पुराना है) , तो यह एक मानक बन गया है)। यह कंस्ट्रक्टरों पर निर्भर नहीं करता है और इसका उपयोग तब भी किया जा सकता है जब मूल्य अपरिभाषित हो। लेकिन यह वस्तुओं के बारे में कोई विवरण नहीं देता है। इसलिए यदि आपको इसकी आवश्यकता है, तो Instof पर जाएं।

अब बात करते हैं एक मुश्किल बात की। यदि आप एक आदिम प्रकार बनाने के लिए कंस्ट्रक्टर का उपयोग करते हैं तो क्या होगा?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

जादू सा लगता है। लेकिन यह नहीं है। यह तथाकथित बॉक्सिंग (ऑब्जेक्ट द्वारा आदिम मूल्य लपेटना) और अनबॉक्सिंग (ऑब्जेक्ट से लिपटे आदिम मूल्य को निकालना) है। इस तरह के कोड को "थोड़ा" नाजुक लगता है। बेशक, आप बस रचनाकारों के साथ आदिम प्रकार बनाने से बच सकते हैं। लेकिन एक और संभावित स्थिति है, जब मुक्केबाजी आपको मार सकती है। जब आप एक आदिम प्रकार पर Function.call () या Function.apply () का उपयोग करते हैं।

function test(){
  console.log(typeof this);
} 
test.apply(5);

इससे बचने के लिए आप सख्त मोड का उपयोग कर सकते हैं:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

अपडेट: ईसीएमएस्क्रिप्ट 2015 के बाद से, सिंबल नामक एक और प्रकार है, जिसका अपना टाइपोफ़ == "प्रतीक" है

console.log(typeof Symbol());
// expected output: "symbol"

आप एमडीएन पर इसके बारे में पढ़ सकते हैं: ( प्रतीक , टाइपोफ )।


2
if an object is created by a given constructor यह गलत है। o instanceof Cयदि ओ। से विरासत में मिला है तो सही वापस आएगा। आपने अपने उत्तर में बाद में इस बारे में कुछ उल्लेख किया है लेकिन यह बहुत स्पष्ट नहीं है।
ओयनामित

1
गलत ... पुस्तक से: " github.com/getify/You-Dont-Know-JS " एक उदाहरण फू; // true इंस्टॉफ़ ऑपरेटर अपने बाएं हाथ के ऑपरेंड के रूप में एक सादे वस्तु लेता है और उसके दाहिने हाथ के ऑपरेंड के रूप में एक फ़ंक्शन। इस सवाल का जवाब है: संपूर्ण [[प्रोटोटाइप]] श्रृंखला में, क्या वस्तु मनमाने ढंग से Foo.prototype द्वारा इंगित की जाती है?
दीन जॉन

1
मैंने उत्तर को संपादित किया है, और अधिक सही होने के लिए। आपकी टिप्पणियों के लिए धन्यवाद।
व्लादिमीर Liubimov

साथ ही, बॉक्सिंग / अनबॉक्सिंग समस्या का स्पष्टीकरण जोड़ा गया।
व्लादिमीर Liubimov

15

मैंने सफारी 5 और इंटरनेट एक्सप्लोरर 9 में वास्तव में कुछ दिलचस्प ("भयानक" के रूप में पढ़ा) की खोज की है। मैं इसे क्रोम और फ़ायरफ़ॉक्स में बड़ी सफलता के साथ उपयोग कर रहा था।

if (typeof this === 'string') {
    doStuffWith(this);
}

तो मैं IE9 में परीक्षण, और यह बिल्कुल काम नहीं करता है। बड़ा आश्चर्य। लेकिन सफारी में, यह आंतरायिक है! इसलिए मैं डिबगिंग शुरू करता हूं, और मुझे लगता है कि इंटरनेट एक्सप्लोरर हमेशा लौट रहा है false। लेकिन सबसे अजीब बात यह है कि सफारी अपने जावास्क्रिप्ट वीएम में किसी प्रकार का अनुकूलन कर रही है true, जहां यह पहली बार है, लेकिन false हर बार जब आप पुनः लोड करते हैं!

मेरा दिमाग लगभग फट गया।

तो अब मैं इस पर बस गया हूं:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

और अब सब कुछ महान काम करता है। ध्यान दें कि आप कॉल कर सकते हैं "a string".toString()और यह केवल स्ट्रिंग की एक प्रति लौटाता है, अर्थात

"a string".toString() === new String("a string").toString(); // true

इसलिए मैं अब से दोनों का उपयोग करूंगा।


8

अन्य महत्वपूर्ण व्यावहारिक अंतर:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true

7

instanceofयह भी काम करता है जब मुझे लगता है कि callbackएक उपप्रकार Functionहै


4

instanceofजावास्क्रिप्ट में परतदार हो सकता है - मेरा मानना ​​है कि प्रमुख ढांचे इसके उपयोग से बचने की कोशिश करते हैं। विभिन्न खिड़कियां उन तरीकों में से एक हैं जिनमें यह टूट सकता है - मेरा मानना ​​है कि वर्ग पदानुक्रम इसे भी भ्रमित कर सकते हैं।

परीक्षण के लिए बेहतर तरीके हैं कि क्या कोई वस्तु एक निश्चित अंतर्निहित प्रकार है (जो आमतौर पर आप चाहते हैं)। उपयोगिता कार्य बनाएं और उनका उपयोग करें:

function isFunction(obj) {
  return typeof(obj) == "function";
}
function isArray(obj) {
  return typeof(obj) == "object" 
      && typeof(obj.length) == "number" 
      && isFunction(obj.push);
}

और इसी तरह।


2
मामले में आप नहीं जानते: टाइपो को कोष्ठक की आवश्यकता नहीं है क्योंकि यह एक कीवर्ड है और फ़ंक्शन नहीं है। और IMHO आपको == के बजाय === का उपयोग करना चाहिए।
कुछ

5
@some आप टाइपोफ़ के बारे में सही हैं लेकिन इस मामले में === की कोई आवश्यकता नहीं है, यह केवल तभी आवश्यक है जब मूल्य की तुलना उसी प्रकार के बिना की जा सकती है। यहाँ, यह नहीं हो सकता।
निकोल

@some टाइपोफ़ कभी एक स्ट्रिंग के अलावा कुछ और लौटाता है?
केनेथ जे

तो, ऐरे के लिए गलत होगा, एक स्टैक ऑब्जेक्ट एक पुश विधि और एक संख्यात्मक लंबाई विशेषता के साथ। किन परिस्थितियों में (उदाहरण के अर्रे) गलत होगा?
क्रिस नू

: @ChrisNoe समस्या वस्तुओं एकाधिक फ्रेम के बीच साझा के साथ उठता है groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/...

3

instanceofआदिमों के लिए काम नहीं करेगा जैसे "foo" instanceof Stringलौट आएगा falseजबकि typeof "foo" == "string"लौट आएगा true

दूसरी ओर typeof, संभवतया ऐसा नहीं होगा जब आप कस्टम ऑब्जेक्ट्स (या कक्षाएं, जो भी आप उन्हें कॉल करना चाहते हैं) की बात आती है। उदाहरण के लिए:

function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog  // true, what we want in this case

यह सिर्फ इतना होता है कि फ़ंक्शन 'फंक्शन' के 'फंक्शन' प्रधानता और उदाहरण दोनों हैं, जो कि एक विषमता का एक सा है जो यह दिया गया है कि यह अन्य आदिम प्रकारों के लिए उस तरह काम नहीं करता है।

(typeof function(){} == 'function') == (function(){} instanceof Function)

परंतु

(typeof 'foo' == 'string') != ('foo' instanceof String)

3

मैं प्रोटोटाइप का उपयोग करने की सलाह दूंगा callback.isFunction()

उन्हें अंतर पता चल गया है और आप उनके कारण पर भरोसा कर सकते हैं।

मुझे लगता है कि अन्य जेएस फ्रेमवर्क में भी ऐसी चीजें हैं।

instanceOfमुझे लगता है कि अन्य खिड़कियों में परिभाषित कार्यों पर काम नहीं करेगा। उनका फंक्शन आपके मुकाबले अलग है window.Function


3

किसी फ़ंक्शन के लिए जाँच करते समय, किसी को हमेशा उपयोग करना चाहिए typeof

यहाँ अंतर है:

var f = Object.create(Function);

console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false

f(); // throws TypeError: f is not a function

यही कारण है कि instanceofएक समारोह के लिए जाँच करने के लिए कभी भी उपयोग नहीं करना चाहिए ।


मैं तर्क दे सकता हूं कि यह typeofगलत है - fनिम्नलिखित में से एक है: एक Object(एक वस्तु) और एक Function(एक फ़ंक्शन)। मेरे अलावा यह उपयोग करने के लिए और अधिक समझ में आता है instanceofक्योंकि यह जानते हुए कि यह एक फ़ंक्शन है मुझे पता है कि यह एक वस्तु है, क्योंकि सभी कार्य ईसीएमएस्क्रिप्ट में ऑब्जेक्ट हैं। आक्षेप सत्य नहीं है - यह जानना typeofकि fवास्तव में objectमेरे पास कोई विचार नहीं है कि यह एक कार्य भी है।
amn

@ मेरे लिए, यह फंक्शन का एक टूटा हुआ उदाहरण है। ऐसा लगता है कि गुण हो जाता है length, nameऔर callसमारोह से, लेकिन उन सभी को मृत कर रहे हैं। क्या बुरा है, यह नहीं कहा जा सकता है और यह TypeErrorकहते हैं f is not a function:।
महाआरती

2

महत्वपूर्ण व्यावहारिक अंतर:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

मुझसे मत पूछो क्यों।


11
क्योंकि यहाँ strएक स्ट्रिंग आदिम है, एक स्ट्रिंग ऑब्जेक्ट नहीं है। वही संख्या प्रधानों और बूलियन प्राइमेटिव्स के लिए जाती है, वे अपने "निर्मित" समकक्षों, स्ट्रिंग, संख्या और बूलियन वस्तुओं के उदाहरण नहीं हैं। जब आवश्यकता होती है तो जावास्क्रिप्ट स्वचालित रूप से इन तीनों प्राथमिकताओं को वस्तुओं में परिवर्तित करता है (जैसे कि वस्तु के प्रोटोटाइप श्रृंखला पर एक विधि का उपयोग करना)। अपने व्यावहारिक अंतर के फ्लिप पक्ष पर, उदाहरण के लिए सरणियों की जांच करने के लिए बेहतर है typeof [] == "object" // true
एंडी ई

2

प्रदर्शन

typeofउन instanceofस्थितियों की तुलना में अधिक तेज़ है जहाँ दोनों लागू हैं।

आपके इंजन के आधार पर, के पक्ष में प्रदर्शन अंतर typeofलगभग 20% हो सकता है । ( आपका माइलेज भिन्न हो सकता है )

यहाँ के लिए एक बेंचमार्क परीक्षण है Array:

var subject = new Array();
var iterations = 10000000;

var goBenchmark = function(callback, iterations) {
    var start = Date.now();
    for (i=0; i < iterations; i++) { var foo = callback(); }
    var end = Date.now();
    var seconds = parseFloat((end-start)/1000).toFixed(2);
    console.log(callback.name+" took: "+ seconds +" seconds.");
    return seconds;
}

// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
     (subject instanceof Array);
}, iterations);

// Testing typeof
var tot = goBenchmark(function typeofTest(){
     (typeof subject == "object");
}, iterations);

var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));

परिणाम

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198

1
टाइपऑफ़ विषय == "सरणी" को गलत लौटना चाहिए। टाइपोफ़ विषय "वस्तु" है।
शार्दुल

टाइपऑफ कैसे तेज होता है? क्या जावास्क्रिप्ट शाब्दिक तार इंटर्निंग है?
ग्रेगरी मगर्कक

इसका कारण है: instanceof हमेशा ऑब्जेक्ट की प्रोटोटाइप श्रृंखला का अनुसरण करता है, इसलिए प्रदर्शन जुर्माना इस बात पर निर्भर करेगा कि प्रोटोटाइप चेन कितनी दूर है, instanceofइसके खिलाफ परीक्षण किया गया है। तो कम वंशानुक्रम श्रृंखला के लिए जुर्माना कम (जैसे [] instanceof Array, {} instanceof Object), और लंबे समय तक - बड़ा होगा। इसलिए, अगर दोनों obj instanceof SomeClassऔर typeof obj !== 'string'आपके काल्पनिक कोड के परिप्रेक्ष्य से समान का मतलब है (फ़े यदि आप सिर्फ एक परीक्षा कर रहे हैं if, और switchकई कक्षाओं आदि के माध्यम से नहीं , तो), तो आप बेहतर दूसरे को चुनेंगे, प्रदर्शन-वार,
अंखेज़

2

यह यहाँ अन्य सभी स्पष्टीकरणों के लिए सिर्फ पूरक ज्ञान है - मैं हर जगह उपयोग करने का सुझाव नहीं दे रहा हूं .constructor

टीएल; डीआर: उन स्थितियों में जहां typeofएक विकल्प नहीं है, और जब आप जानते हैं कि आप प्रोटोटाइप श्रृंखला के बारे में परवाह नहीं करते हैं , Object.prototype.constructorतो एक व्यवहार्य या इससे भी बेहतर विकल्प हो सकता है instanceof:

x instanceof Y
x.constructor === Y

यह 1.1 से मानक में है, इसलिए पीछे की संगतता के बारे में कोई चिंता नहीं है।

मुहम्मद उमर ने कुछ समय पहले यहां एक टिप्पणी में इसका उल्लेख किया था। यह एक प्रोटोटाइप के साथ सब कुछ पर काम करता है - इसलिए सब कुछ nullया नहीं undefined:

// (null).constructor;      // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties

(1).constructor;                 // function Number
''.constructor;                  // function String
([]).constructor;                // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor;               // function Boolean()
true.constructor;                // function Boolean()

(Symbol('foo')).constructor;     // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor

Array.prototype === window.frames.Array;               // false
Array.constructor === window.frames.Array.constructor; // true

इसके अलावा, आपके उपयोग के मामले पर निर्भर करता है कि यह बहुत तेजी से हो सकता है instanceof(कारण यह है कि यह पूरी प्रोटोटाइप श्रृंखला की जांच नहीं करता है)। मेरे मामले में मुझे यह जांचने के लिए तेज़ तरीका चाहिए था कि क्या कोई मान टाइप किया गया है:

function isTypedArrayConstructor(obj) {
  switch (obj && obj.constructor){
    case Uint8Array:
    case Float32Array:
    case Uint16Array:
    case Uint32Array:
    case Int32Array:
    case Float64Array:
    case Int8Array:
    case Uint8ClampedArray:
    case Int16Array:
      return true;
    default:
      return false;
  }
}

function isTypedArrayInstanceOf(obj) {
  return obj instanceof Uint8Array ||
    obj instanceof Float32Array ||
    obj instanceof Uint16Array ||
    obj instanceof Uint32Array ||
    obj instanceof Int32Array ||
    obj instanceof Float64Array ||
    obj instanceof Int8Array ||
    obj instanceof Uint8ClampedArray ||
    obj instanceof Int16Array;
}

https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812

और परिणाम:

Chrome 64.0.3282.167 (64-बिट, विंडोज)

टाइप किए गए ऐरे इंस्टोफ़ बनाम कंस्ट्रक्टर - क्रोम 64.0.3282.167 (64-बिट, विंडोज) में 1.5x तेज़

फ़ायरफ़ॉक्स 59.0b10 (64-बिट, विंडोज)

टाइप किए गए ऐरे इंस्टोफ़ बनाम कंस्ट्रक्टर - फ़ायरफ़ॉक्स में 30x तेज़ 59.0b10 (64-बिट, विंडोज)

जिज्ञासा से बाहर, मैंने एक त्वरित खिलौना बेंचमार्क के खिलाफ किया typeof; आश्चर्यजनक रूप से यह बहुत बुरा प्रदर्शन नहीं करता है, और यह क्रोम में थोड़ा तेज लगता है:

let s = 0,
    n = 0;

function typeofSwitch(t) {
    switch (typeof t) {
        case "string":
            return ++s;
        case "number":
            return ++n;
        default:
            return 0;
    }
}

// note: no test for null or undefined here
function constructorSwitch(t) {
    switch (t.constructor) {
        case String:
            return ++s;
        case Number:
            return ++n;
        default:
            return 0;
    }
}

let vals = [];
for (let i = 0; i < 1000000; i++) {
    vals.push(Math.random() <= 0.5 ? 0 : 'A');
}

https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570

नोट: आदेश जिसमें कार्य छवियों के बीच सूचीबद्ध स्विच हैं!

Chrome 64.0.3282.167 (64-बिट, विंडोज)

स्ट्रिंग / संख्या टाइपोफ़ बनाम निर्माता - क्रोम 64.0.3282.167 (64-बिट, विंडोज) में 1.26x तेज़

फ़ायरफ़ॉक्स 59.0b10 (64-बिट, विंडोज)

नोट: आदेश जिसमें कार्य छवियों के बीच सूचीबद्ध स्विच हैं!

स्ट्रिंग / नंबर टाइपोफ़ कंस्ट्रक्टर - फ़ायरफ़ॉक्स 59.0b10 में 0.78x धीमा (64-बिट, विंडोज)


1

Instof का उपयोग करें क्योंकि यदि आप वर्ग का नाम बदलते हैं तो आपको एक कंपाइलर त्रुटि मिलेगी।


1

var newObj =  new Object;//instance of Object
var newProp = "I'm xgqfrms!" //define property
var newFunc = function(name){//define function 
	var hello ="hello, "+ name +"!";
	return hello;
}
newObj.info = newProp;// add property
newObj.func = newFunc;// add function

console.log(newObj.info);// call function
// I'm xgqfrms!
console.log(newObj.func("ET"));// call function
// hello, ET!

console.log(newObj instanceof Object);
//true
console.log(typeof(newObj));
//"object"


मुझे क्या करना चाहिए, क्या मुझे UA (navigator.userAgent) मिल सकता है?
xgqfrms

0

एक सख्त OO परवरिश से आने के लिए मैं जाऊंगा

callback instanceof Function

स्ट्रिंग्स या तो मेरी भयानक वर्तनी या अन्य टाइपोस के लिए प्रवण हैं। इसके अलावा मुझे लगता है कि यह बेहतर है।


0

बावजूद instanceof एक छोटा सा तेजी से तो हो सकता है typeof , मैं इस तरह के एक संभव जादू की वजह से एक दूसरे को पसंद करते हैं:

function Class() {};
Class.prototype = Function;

var funcWannaBe = new Class;

console.log(funcWannaBe instanceof Function); //true
console.log(typeof funcWannaBe === "function"); //false
funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function

0

एक और मामला यह है कि आप केवल इससे टकरा सकते हैं instanceof- यह सही या गलत है। typeofआप के साथ प्रदान की कुछ प्रकार प्राप्त कर सकते हैं


0

प्रदर्शन को ध्यान में रखते हुए, आप एक विशिष्ट हार्डवेयर के साथ टाइपोफ़ का बेहतर उपयोग करेंगे, यदि आप एक स्क्रिप्ट बनाते हैं जिसमें 10 मिलियन का एक लूप होता है जो निर्देश को निर्देश देता है: टाइपऑफ़ str == 'string' में 9ms लगेंगे जबकि 'string' instof स्ट्रिंग में 19ms लगेंगे


0

बेशक यह मायने रखता है ........!

चलिए इसे उदाहरणों के माध्यम से चलते हैं। हमारे उदाहरण में हम दो अलग-अलग तरीकों से कार्य की घोषणा करेंगे।

हम दोनों function declarationऔर फंक्शन कन्स्ट्रक्टर का उपयोग करेंगे । हम कैसे करेंगेtypeofinstanceof उन दो अलग-अलग परिदृश्यों में और का बर्ताव ।

फ़ंक्शन घोषणा का उपयोग करके फ़ंक्शन बनाएं:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

इस तरह के विभिन्न परिणाम के लिए संभावित स्पष्टीकरण है, जैसा कि हमने एक फ़ंक्शन घोषणा की, typeofसमझ सकते हैं कि यह एक फ़ंक्शन है। क्योंकि typeofचेक इस बात की जांच करता है कि टाइपऑफ़ किस पर संचालित है या नहीं, हमारे मामले में कॉल विधि लागू की गई है या नहीं । यदि यह विधि लागू करता है, तो यह एक कार्य है। इसके अलावा। नहीं। स्पष्टीकरण की जाँच करेंMyFunc Call। अन्य प्रकार के लिए। नहीं लिए

फ़ंक्शन कंस्ट्रक्टर का उपयोग करके फ़ंक्शन बनाएं:

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

यहां बताया गया typeofहै कि MyFunc2यह एक फ़ंक्शन है और साथ instanceofही ऑपरेटर भी है। हम पहले से ही जानते हैं कि typeofक्या MyFunc2लागू किया गया Callतरीका है या नहीं। MyFunc2एक फ़ंक्शन है और यह callविधि लागू करता है, typeofयह है कि यह कैसे जानता है कि यह एक फ़ंक्शन है। दूसरी ओर, हम इसे function constructorबनाने के लिए उपयोग करते हैं MyFunc2, एक उदाहरण बन जाता है Function constructorinstanceofयह भी क्यों हल होता है true

उपयोग करने के लिए क्या सुरक्षित है?

जैसा कि हम दोनों मामलों में देख सकते हैं typeofकि ऑपरेटर सफलतापूर्वक यह दावा कर सकता है कि हम यहां एक समारोह के साथ काम कर रहे हैं, यह अधिक सुरक्षित है instanceofinstanceofके मामले में विफल रहेगा function declarationक्योंकि function declarationsकोई उदाहरण नहीं है Function constructor

सर्वश्रेष्ठ प्रणालियां :

जैसा कि गैरी रैफर्टी ने सुझाव दिया था, सबसे अच्छा तरीका दोनों टाइपोफ और इंस्टोफ का एक साथ उपयोग करना चाहिए।

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter

इस उत्तर के बारे में किसी भी रचनात्मक आलोचना की सराहना की जाएगी।
अल-ज़मी

0

बहुत सटीक उदाहरण के लिए इस्तेमाल किया जाना चाहिए, जहां उदाहरण के लिए कंस्ट्रक्टर (आमतौर पर कस्टम प्रकार) के माध्यम से मूल्य बनाया जाता है

var d = new String("abc")

जबकि टाइपो को उदाहरण के लिए असाइनमेंट द्वारा बनाए गए मानों की जांच करना

var d = "abc"

0

ऊपर दिए गए उदाहरणों के टन के साथ डूबने की कोई आवश्यकता नहीं है, बस दो बिंदुओं को ध्यान में रखें:

  1. typeof var;एक अपर ऑपरेटर मूल प्रकार या मूल प्रकार का var लौटाएगा। तो यह आदिम प्रकार (वापस आ जाएगी कि string, number, bigint, boolean, undefined, और symbol) या objectप्रकार।

  2. उच्च-स्तरीय ऑब्जेक्ट के मामले में, बिल्ट-इन ऑब्जेक्ट्स की तरह (स्ट्रिंग, संख्या, बूलियन, एरे ..) या जटिल या कस्टम ऑब्जेक्ट, ये सभी objectरूट प्रकार हैं, लेकिन उन पर निर्मित प्रकार का आधार भिन्न होता है (जैसे OOP वर्ग इनहेरिटेंस कॉन्सेप्ट), यहाँ a instanceof A- एक बाइनरी ऑपरेटर - आपकी मदद करेगा, यह प्रोटोटाइप चेन के माध्यम से जाँच करेगा कि सही ऑपरेटर (ए) का कंस्ट्रक्टर दिखाई देता है या नहीं।

इसलिए जब भी आप "रूट प्रकार" की जांच करना चाहते हैं या आदिम चर के साथ काम करना चाहते हैं - "टाइपोफ़" का उपयोग करें, अन्यथा "इंस्टाफॉफ़" का उपयोग करें।

nullएक विशेष मामला है, जो प्रतीत होता है आदिम है, लेकिन वास्तव में वस्तु के लिए एक विशेष मामला है। a === nullइसके बजाय नल की जांच करने के लिए उपयोग करना ।

दूसरी ओर, functionएक विशेष मामला भी है, जो अंतर्निहित वस्तु है, लेकिन typeofवापस आ जाता हैfunction

जैसा कि आप देख सकते हैं instanceofकि प्रोटोटाइप श्रृंखला के माध्यम से जाना चाहिए इस बीच typeofबस रूट प्रकार की एक बार जांच करें ताकि यह समझना आसान हो कि क्यों typeofतेजी से हैinstanceof


0

टाइपो के बारे में एमडीएन प्रलेखन के अनुसार , "नए" कीवर्ड के साथ तात्कालिक वस्तुएं 'ऑब्जेक्ट' प्रकार की होती हैं:

typeof 'bla' === 'string';

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === 'object'; 
typeof new Number(1) === 'object'; 
typeof new String('abc') === 'object';

उदाहरण के बिंदुओं के बारे में दस्तावेज़ीकरण करते समय :

const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true

इसलिए यदि कोई उदाहरण के लिए जाँचना चाहता है कि कोई चीज कोई स्ट्रिंग नहीं है तो इसे कैसे बनाया जाए, इसका उपयोग करने के लिए सबसे सुरक्षित तरीका होगा instanceof

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