parseInt बनाम unary plus, कब किसका उपयोग करना है?


149

इस लाइन के बीच क्या अंतर हैं:

var a = parseInt("1", 10); // a === 1

और यह पंक्ति

var a = +"1"; // a === 1

इस jsperf टेस्ट से पता चलता है कि वर्तमान क्रोम संस्करण में unary ऑपरेटर बहुत तेज है, यह मानते हुए कि यह नोड के लिए है !?!

यदि मैं उन स्ट्रिंग्स को बदलने की कोशिश करता हूं जो दोनों रिटर्न नहीं हैं NaN:

var b = parseInt("test" 10); // b === NaN
var b = +"test"; // b === NaN

तो मुझे parseIntयूनीरी प्लस (विशेषकर नोड.जेएस पर) का उपयोग कब करना चाहिए ???

संपादित करें : और डबल टिल्ड ऑपरेटर से क्या अंतर है ~~?


जवाबों:


169

कृपया इस उत्तर को मामलों के अधिक पूर्ण सेट के लिए देखें




खैर, यहाँ कुछ अंतर हैं जो मुझे पता है:

  • एक खाली स्ट्रिंग एक का ""मूल्यांकन करती है 0, जबकि parseIntइसका मूल्यांकन करती है NaN। IMO, एक रिक्त स्ट्रिंग होना चाहिए a NaN

    +'' === 0;              //true
    isNaN(parseInt('',10)); //true
  • एकाकी +अधिक कार्य करता है parseFloatक्योंकि यह भी दशमलव को स्वीकार करता है।

    parseIntदूसरी ओर जब यह एक गैर-संख्यात्मक चरित्र को देखता है, तो उस अवधि को रोक देता है, जैसे उस अवधि को दशमलव बिंदु माना जाता है .

    +'2.3' === 2.3;           //true
    parseInt('2.3',10) === 2; //true
  • parseIntऔर parseFloatपार्स करता है और बाएं से दाएं स्ट्रिंग बनाता है । यदि उन्हें एक अमान्य चरित्र दिखाई देता है, तो वह वापस लौटता है जिसे एक संख्या के रूप में पार्स किया गया है (यदि कोई हो), और NaNयदि कोई भी संख्या के रूप में पार्स नहीं किया गया है।

    +दूसरी ओर यूनियरी वापस आ जाएगी NaNयदि पूरा स्ट्रिंग संख्या में गैर-परिवर्तनीय है।

    parseInt('2a',10) === 2; //true
    parseFloat('2a') === 2;  //true
    isNan(+'2a');            //true
  • जैसा कि @Alex K. की टिप्पणी में देखा गया है , parseIntऔर parseFloatचरित्र द्वारा पार्स करेंगे। इसका मतलब है कि हेक्स और एक्सपोनेंट नोटेशन विफल हो जाएंगे xऔर eगैर-संख्यात्मक घटकों (कम से कम बेस 10 पर) के रूप में माना जाता है।

    एकल +उन्हें ठीक से हालांकि परिवर्तित कर देंगे।

    parseInt('2e3',10) === 2;  //true. This is supposed to be 2000
    +'2e3' === 2000;           //true. This one's correct.
    
    parseInt("0xf", 10) === 0; //true. This is supposed to be 15
    +'0xf' === 15;             //true. This one's correct.

6
मूलांक का उपयोग करते समय भी+"0xf" != parseInt("0xf", 10)
एलेक्स के।

मुझे आपका अब तक का जवाब पसंद है, क्या आप यह भी बता सकते हैं कि डबल टिल्ड ऑपरेटर ~~ में क्या अंतर है?
hereandnow78

@ hereandnow78 कि यहाँ समझाया जाएगा । यह बिटवाइज़ के बराबर है Math.floor(), जो मूल रूप से दशमलव भाग को काट देता है।
जोसफ

4
वास्तव में, के "2e3"लिए एक वैध पूर्णांक प्रतिनिधित्व नहीं है 2000। यह एक मान्य फ़्लोटिंग पॉइंट संख्या है, हालांकि: उत्तर के रूप में parseFloat("2e3")सही 2000रूप से उपज देगा । और "0xf"कम से कम आधार 16 की आवश्यकता है, यही कारण है कि parseInt("0xf", 10)रिटर्न 0, जबकि parseInt("0xf", 16)15 का मूल्य जो आप उम्मीद कर रहे थे।
बार्ट

2
@Joseph Dreamer और @ hereandnow78: संख्या के दशमलव भाग से दोगुना टिल्ड काट देता है, जबकि Math.floor निकटतम निचला नंबर देता है। वे सकारात्मक संख्या के लिए समान काम करते हैं, लेकिन Math.floor(-3.5) == -4और ~~-3.5 == -3
एल्बिन

261

अंतिम जो कुछ भी संख्या रूपांतरण तालिका: रूपांतरण तालिका


2
कृपया "NaN"इस तालिका में जोड़ें ।
छरवे

यह isNaNइस तालिका में एक स्तंभ जोड़ने के लायक हो सकता है : उदाहरण के लिए, isNaN("")गलत है (यानी यह एक संख्या माना जाता है), लेकिन parseFloat("")है NaN, जो एक गोत्र हो सकता है, यदि आप isNaNइसे पास करने से पहले इनपुट को मान्य करने के लिए उपयोग करने का प्रयास कर रहे हैंparseFloat
रट्सम

आपको '{valueOf: function(){return 42}, toString: function(){return "56"}}'सूची में भी जोड़ना चाहिए । मिश्रित परिणाम दिलचस्प हैं।
मुरैजू

3
तो, तालिका का सारांश यह है कि +लेखन का सिर्फ एक छोटा तरीका है Number, और फुर्तीले लोग इसे करने के लिए सिर्फ पागल तरीके हैं जो किनारे के मामलों में विफल होते हैं?
मिहेल मैलोस्टैनिडिस

क्या [] .undef एक बात है, या यह है कि केवल एक मनमाने ढंग से अनिर्धारित उत्पादन का तरीका है? Google के माध्यम से JS से संबंधित "अपरिभाषित" का कोई रिकॉर्ड नहीं मिल सकता है।
जेकेरनी 20

10

Thg435 के उत्तर में तालिका मेरा मानना ​​है कि व्यापक है, हालांकि हम निम्नलिखित पैटर्न के साथ संक्षेप में बता सकते हैं:

  • यूनीरी प्लस सभी मिथ्या मूल्यों का एक समान व्यवहार नहीं करता है, लेकिन वे सभी झूठे निकलते हैं।
  • एकल प्लस भेजता है true1 करने के लिए, लेकिन "true"करने के लिए NaN
  • दूसरी ओर, parseIntउन तारों के लिए अधिक उदार है जो शुद्ध अंक नहीं हैं। parseInt('123abc') === 123, जबकि +रिपोर्ट NaN
  • Numberमान्य दशमलव संख्याओं को स्वीकार करेगा, जबकि parseIntदशमलव में सब कुछ छोड़ देता है। इस प्रकार parseIntसी व्यवहार की नकल करता है, लेकिन उपयोगकर्ता इनपुट के मूल्यांकन के लिए शायद आदर्श नहीं है।
  • दोनों ने तार में व्हाट्सएप ट्रिम कर दिया।
  • parseIntएक बुरी तरह से डिज़ाइन किए गए पार्सर के रूप में , अष्टा और हेक्साडेसिमल इनपुट को स्वीकार करता है। यूनीरी प्लस केवल षोडश आधारी लेता है।

मिथ्या मूल्य Numberसी में क्या मतलब होगा निम्नलिखित को परिवर्तित करते हैं : nullऔर falseदोनों शून्य हैं। ""0 पर जाने से इस सम्मेलन का काफी पालन नहीं होता है, लेकिन यह मेरे लिए काफी मायने रखता है।

इसलिए मुझे लगता है कि यदि आप उपयोगकर्ता इनपुट को मान्य कर रहे हैं, तो यूनिरी प्लस के पास हर चीज के लिए सही व्यवहार है, सिवाय इसके कि यह दशमलव को स्वीकार करता है (लेकिन मेरे वास्तविक जीवन के मामलों में मुझे उपयोगकर्ता इनपुट के बजाय ईमेल इनपुट को पकड़ने में अधिक रुचि है, मान पूरी तरह से छोड़ा गया है, आदि), जबकि parseInt बहुत उदार है।


2
"यूनीरी प्लस केवल हेक्साडेसिमल लेता है" क्या आपका मतलब दशमलव नहीं है?
क्रिलगर

0

लापरवाह बनो, ParseInt Node.JS में + unary ऑपरेटर की तुलना में तेज़ है, यह गलत है कि + = 0 अधिक तेज़ हैं, वे केवल NaN तत्वों के लिए तेज़ हैं।

इसकी जांच करें:

var arg=process.argv[2];

rpt=20000;
mrc=1000;

a=[];
b=1024*1024*1024*1024;
for (var i=0;i<rpt;i++)
 a[i]=Math.floor(Math.random()*b)+' ';

t0=Date.now();
if ((arg==1)||(arg===undefined))
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  c=a[i]-0;
 }
t1=Date.now();
if ((arg==2)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  d=a[i]|0;
 }
}
t2=Date.now();
if ((arg==3)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  e=parseInt(a[i]);
 }
}
t3=Date.now();
 if ((arg==3)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  f=+a[i];
 }
}
t4=Date.now();

console.log(a[i-1],c,d,e,f);
console.log('Eseguiti: '+rpt*mrc+' cicli');
console.log('parseInt '+(t3-t2));
console.log('|0 '+(t2-t1));
console.log('-0 '+(t1-t0));
console.log('+ '+(t4-t3));

-3

प्रदर्शन पर विचार करें भी । मुझे आश्चर्य हुआ कि parseIntआईओएस पर यूनियरी प्लस धड़कता है :) यह केवल भारी सीपीयू खपत वाले वेब ऐप के लिए मददगार है। एक नियम के रूप में, मैं सुझाव दूंगा कि जेएस ऑप्ट-लोग आजकल के मोबाइल प्रदर्शन बिंदु से किसी अन्य जेएस ऑपरेटर पर विचार करें।

तो, मोबाइल पहले जाओ ;)


जैसा कि अन्य पोस्ट बताते हैं कि वे काफी अलग चीजें करते हैं, इसलिए आप आसानी से एक दूसरे के लिए स्वैप नहीं कर सकते ...
बरगी

@ बर्गी, सही है, लेकिन उनमें भी बहुत कुछ है। मुझे जावास्क्रिप्ट में सिर्फ एक प्रदर्शन समाधान बताएं जो निश्चित रूप से एकमात्र सही विकल्प है? सामान्य तौर पर यही कारण है कि नियम-अंगूठे हमारे लिए हैं। शेष कार्य-विशिष्ट है।
अरमान मैकहिटेरियन जूल

3
@ArmanMcHitaryan यह व्यर्थ माइक्रोपोप्टिमेशन है और यह इसके लायक नहीं है। इस लेख को देखें - fabien.potencier.org/article/8/…
webvitaly

@webvitaly, अच्छा लेख। वहाँ हमेशा बहुत पूर्ण उन्मुख लोग हैं जो सिर्फ "सबसे तेज़ संभव" कोड लिखना चाहते हैं और कुछ विशिष्ट परियोजनाओं में जो खराब नहीं हैं। इसलिए मैंने "जेएस ऑप्ट-पर विचार करने वाले लोगों" का उल्लेख किया। यह निश्चित रूप से MUST नहीं है :), लेकिन मैं खुद को इसके अलावा बहुत अधिक पठनीय मानता हूं।
अरमान मैकहिटेरियन

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