كيف يمكنني التغلب على سلوك parseInt الثماني لجافا سكريبت؟

StackOverflow https://stackoverflow.com/questions/850341

  •  21-08-2019
  •  | 
  •  

سؤال

حاول تنفيذ ما يلي في JavaScript:

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

لقد تعلمت للتو بالطريقة الصعبة التي تعتقد بها JavaScript أن الصفر البادئ يشير إلى عدد صحيح ثماني, ، وبما أنه لا يوجد "8" أو "9" في الأساس 8، ترجع الدالة صفرًا.أعجبك أم لا، هذا حسب التصميم.

ما هي الحلول؟

ملحوظة:من أجل الاكتمال، أنا على وشك نشر حل، لكنه حل أكرهه، لذا يرجى نشر إجابات أخرى/أفضل.


تحديث:

الإصدار الخامس من معيار جافا سكريبت (إكما-262) يقدم تغييرًا جذريًا يزيل هذا السلوك.موزيلا لديها جيدة الكتابة.

هل كانت مفيدة؟

المحلول

هذه مشكلة شائعة في جافا سكريبت مع حل بسيط:

فقط تحديد القاعدة, ، أو "الجذر"، مثل ذلك:

parseInt('08',10); // 8

يمكنك أيضًا استخدام رقم:

Number('08'); // 8

نصائح أخرى

اذا أنت يعرف ستكون القيمة الخاصة بك في نطاق عدد صحيح 32 بت، بعد ذلك ~~x سوف تفعل الشيء الصحيح في جميع السيناريوهات.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

إذا بحثت عن ثنائي لا (~)، تتطلب المواصفات تحويل "ToInt32" للوسيطة التي تقوم بالتحويل الواضح إلى Int32 ويتم تحديدها للإكراه NaN القيم إلى الصفر.

نعم، هذا أمر اختراقي بشكل لا يصدق ولكنه مريح للغاية...

من وثائق parseInt, ، استخدم وسيطة radix الاختيارية لتحديد الأساس 10:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

يبدو لي هذا متحذلقًا ومربكًا ومطولًا (في الحقيقة، حجة إضافية في كل parseInt؟) لذلك آمل أن تكون هناك طريقة أفضل.

function parseDecimal(s) { return parseInt(s, 10); }

يحرر:إن إنشاء وظيفتك الخاصة، للقيام بما تريده حقًا، هو مجرد خيار إذا كنت لا ترغب في إضافة "،10" طوال الوقت إلى استدعاء parseInt().لها عيب كونها وظيفة غير قياسية:أكثر ملاءمة لك إذا كنت تستخدمه كثيرًا، ولكن ربما يكون أكثر إرباكًا للآخرين.

تحديد القاعدة:

var number = parseInt(s, 10);

هل سيكون من غير اللائق استبدال parseInt بإصدار يفترض العلامة العشرية إذا لم يكن به معلمة ثانية؟(ملاحظة - لم يتم اختباره)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

ماذا عن هذا بالنسبة للعلامة العشرية:

('09'-0) === 9  // true

('009'-0) === 9 // true

يمكنك أيضًا، بدلاً من استخدام parseFloat أو parseInt، استخدام العامل الأحادي (+).

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

ولحسن التدبير

+"09.09"
// => 9.09

رابط مدن

يسبق عامل التشغيل الأحادي المعامل الخاص به ويقيم المعامل الخاص به ولكنه يحاول تحويله إلى رقم، إذا لم يكن كذلك بالفعل.على الرغم من أن النفي الأحادي (-) يمكنه أيضًا تحويل الأرقام غير، Unary Plus هي الطريقة الأسرع والمفضلة لتحويل شيء ما إلى رقم, لأنه لا يقوم بأي عمليات أخرى على الرقم.

إذا كنت قد قمت بالفعل بمجموعة من التعليمات البرمجية باستخدام parseInt ولا تريد إضافة "،10" إلى كل شيء، فيمكنك فقط تجاوز الوظيفة لجعل الأساس 10 هو الإعداد الافتراضي:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

قد يربك ذلك قارئًا لاحقًا، لذا فإن إنشاء دالة parseInt10() قد يكون أكثر وضوحًا.أنا شخصياً أفضل استخدام وظيفة بسيطة بدلاً من الاضطرار إلى إضافة "،10" طوال الوقت - فقط يخلق المزيد من الفرص للأخطاء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top