خروجی
typeof null
توی جاوااسکریپت برابر میشه با
"object"
که به نادرستی این معنی رو منتقل میکنه که
null
یه آبجکت (شیء) هست (در صورتی که نیست.
null
یه
primitive value
یا مقدار اولیه هست). این یه باگه و چون کدهای فعلی از کار میافتن نمیشه رفعش کرد.
باگ «typeof null» بازماندهی اولین نسخهی جاوااسکریپته. توی اون نسخه، مقادیر در واحدهای ۳۲بیتی ذخیره میشدن که از یه برچسب ۱ الی ۳ بیتی برای تشخیص نوع و از بقیهی بیتها برای ذخیره کردن مقدار اصلی داده استفاده میشد. «برچسب نوع داده» در بیتهای کمارزش ذخیره میشدن. پنجتا از این برچسبها وجود داشت:
- 000: آبجکت. داده به یه آبجکت اشاره میکنه.
- 1: عدد صحیح (int). داده یه عدد صحیح علامتدار (signed integer) ۳۱بیتی هست.
- 010: عدد double. داده یه مرجع به یه عدد اشعاری double هست.
- 100: رشته (string). داده یه مرجع به یه رشته هست.
- 110: بولی (boolean). داده یه بولین هست.
اگه بیارزشترین بیت مقدارش 1 بود، برچسب نوع داده یه بیتی بود و اگه بیارزشترین بیت 0 بود، برچسب نوع داده ۳ بیتی بود، که از دو بیت اضافهتر، برای تعیین چهار نوع داده مختلف استفاده میشد.
دو مقدار ویژه هم وجود داشتن:
- مقدار
undefined
یا JSVAL_VOID که عدد صحیح 32^2- بود (یه عدد خارج از محدودهی اعداد صحیح). - مقدار
null
یا JSVAL_NULL که کد ماشین اشارهگر NULL بود: یه نوع داده آبجکت که مقدار اشارهگرش 0 بود.
الان دیگه باید واضح باشه که چرا
typeof null
خروجی آبجکت رو پاسخ میده: چون برچسبِ نوع داده رو چک میکنه و میبینه که برابر با آبجکت هست. کد اولین موتور جاوااسکریپت برای
typeof:
گامهایی که کد بالا طی میکنه:
- گام (1): موتور بررسی میکنه که آیا مقدار v برابر با undefined یا همون JSVAL_VOID هست یا نه. این بررسی با یه دستور برابر انجام میشه:
1#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
- بررسی بعدی (2) اینه که آیا مقدار مورد نظر، برچسب آبجکت داره یا نه. علاوهبر این اگه مقدار
v
قابل صدازدنه یا به عبارتی
callable
هست (3)
یا ویژگی داخلی
[[Class]]
اون داره میگه که یه تابع هست (4)
پس بنابراین
v
یه تابعه. در غیر این صورت، یه آبجکته.
این خروجیایه که برایtypeof null
تولید میشه. - بررسیهای بعدی برای اعداد، رشتهها و بولین هست. هیچ بررسی صریحی برای مقدار null وجود نداره، که میتونست خیلی راحت با یه ماکرو C انجام بشه:
1#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL)
این باگ شاید خیلی واضح به نظر بیاد، اما نباید فراموش کرد که برای نوشتن اولین نسخهی جاوااسکریپت زمان خیلی کمی در اختیارشون بوده!
منبع: The history of typeof null از وبلاگ 2ality - JavaScript and more