برنامه نویسی

آیا NaN در واقع به معنای یک عدد نیست؟

در نظر بگیرید که ما باید عملیات ریاضی زیر را انجام دهیم:

var a =  13 / "bar"; 

console.log(a); // NaN
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

هر عملیات ریاضی بدون اینکه هر دو عملوند اعداد باشند انجام دهیم، منجر به عدم تولید یک عدد معتبر می‌شود که آن را به عنوان NaN.

از عملیات فوق، a NaN است و اگر انجام دهیم:

console.log(typeof a === "number") // true
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از بالا، اگر NaN به معنای عدد نیست، از بالا می توان گفت که “نوع غیر یک عدد عدد است!”.

گیج کننده است نه؟

بیایید بیشتر در مورد NaN صحبت کنیم؟

این کاملاً دقیق نیست که NaN را به عنوان “عدد” در نظر بگیریم. در عوض، دقیق تر است که آن را به عنوان یک “عدد نامعتبر”، “عدد شکست خورده” یا حتی “عدد بد” تصور کنیم.

NaN نوعی “مقدار نگهبان” است که نوع خاصی از شرایط خطا را در مجموعه اعداد نشان می دهد. ما می توانیم در مورد آن فکر کنیم: “سلام، من سعی کردم یک عملیات ریاضی را انجام دهم اما ناموفق بود، بنابراین در عوض نتیجه عدد ناموفق است“.

حال اگر مقداری در یک متغیر داشته باشیم و بخواهیم آزمایش کنیم و ببینیم که آیا این عدد ناموفق خاص NaN است، چگونه این کار را انجام خواهیم داد؟

اولین چیزی که به ذهن ما می رسد این است که از عملگرهای مقایسه استفاده کنیم و با استفاده از آنها می توانیم متغیر را با خود NaN مقایسه کنید.

ساده نیست؟ ببینم….

var a =  13 / "bar";

console.log(a == NaN) // false
console.log(a === NaN) // false
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سردرگمی بیشتر نیست؟ بیایید کمی بیشتر در مورد NaN بدانیم.

NaN یک مقدار بسیار ویژه است زیرا هرگز با مقدار NaN دیگری برابر نیست. (یعنی هرگز با خودش برابر نیست).

بنابراین حتی اگر زیر را انجام دهیم:

console.log(a == a) // false
console.log(a === a) // false
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نتایج در هر دو مورد نادرست خواهد بود. NaN تنها مقدار در کل زبان است که NaN با خودش برابر نیست.

حال این سوال پیش می آید که اگر نتوانیم NaN را مقایسه کنیم چگونه آن را آزمایش کنیم؟

برای این کار، ما از یک تابع جهانی داخلی به نام isNan(…) استفاده می کنیم.

var a =  13 / "bar";

console.log(isNaN(a)) // true
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به اندازه کافی ساده درست است؟

در واقع این isNan(…) یک نقص کشنده دارد. به نظر می رسد که معنای NaN به عنوان یک عدد را بیش از حد تحت اللفظی می گیرد.

مثال زیر را ببینید:

var a =  13 / "bar";
var b = "foo";

console.log(isNaN(a)) // true
console.log(isNaN(b)) // true
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از مثال بالا، فقط بررسی می کند که “آیا چیز ارسال شده یک عدد است یا نه”.

واضح است که “foo” به معنای واقعی کلمه یک عدد نیست، اما قطعاً مقدار NaN نیز نیست. این باگ در JS از همان ابتدا وجود دارد.

از ES6، بالاخره یک ابزار جایگزین ارائه شد: Number.isNaN(…) که مشکل فوق را حل می کند.

Polyfill ساده برای بررسی مقادیر NaN در مرورگرهای قبل از ES6 به شرح زیر است:

if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return(
            typeof n === 'number' && isNaN(n)
        );
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما می توانیم این Polyfill را با استفاده از این واقعیت که NaN با خودش برابر نیست، به روشی آسان پیاده سازی کنیم.

if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return n !== n;
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر در حال حاضر فقط از isNaN(…) در یک برنامه استفاده می کنید، واقعیت غم انگیز این است که برنامه شما دارای یک اشکال است، حتی اگر هنوز توسط آن گاز نخورده باشید. بنابراین اکنون ایده بسیار خوبی برای استفاده از تست قابل اعتماد است، مانند Number.isNaN(…) همانطور که ارائه شده است.

این همه برای موضوع است. امیدوارم دوست داشته باشید.

مرجع: شما JS را نمی شناسید اثر کایل سیمپسون

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

همچنین ببینید
بستن
دکمه بازگشت به بالا