We are still cooking the magic in the way!
أنواع البيانات وتحويل الأنواع
فهم أنواع البيانات في JavaScript
كل قيمة في JavaScript لها نوع محدد. فهم أنواع البيانات أمر أساسي لأنها تحدد العمليات التي يمكنك إجراؤها على القيمة، وكيف يتم تخزين القيم في الذاكرة، وكيف تتصرف JavaScript عند دمج أنواع مختلفة. JavaScript هي لغة ديناميكية الأنواع، مما يعني أن المتغيرات ليس لها أنواع ثابتة -- المتغير الذي يحمل رقما يمكن أن يحمل لاحقا نصا. هذه المرونة قوية، لكنها تعني أيضا أنك يجب أن تفهم كيف تعمل الأنواع لتجنب الأخطاء الدقيقة.
تحتوي JavaScript على فئتين من أنواع البيانات: الأنواع البدائية والأنواع المرجعية (الكائنات). في هذا الدرس، نركز بالكامل على الأنواع البدائية التي تشكل اللبنات الأساسية لجميع البيانات في JavaScript. هناك سبعة أنواع بدائية: string، number، bigint، boolean، undefined، null، symbol. كل نوع يتصرف بشكل مختلف ويخدم غرضا مميزا في برامجك.
نوع النص (String)
النصوص تمثل البيانات النصية. يمكنك إنشاء النصوص باستخدام علامات الاقتباس المفردة أو المزدوجة أو العلامات الخلفية (القوالب النصية). جميعها تنتج قيما نصية، لكن القوالب النصية توفر ميزات إضافية مثل التعبيرات المضمنة والنصوص متعددة الأسطر.
مثال: إنشاء النصوص
// علامات اقتباس مفردة
let firstName = 'Alice';
// علامات اقتباس مزدوجة
let lastName = "Johnson";
// القوالب النصية (العلامات الخلفية)
let greeting = `Hello, ${firstName} ${lastName}!`;
console.log(greeting); // "Hello, Alice Johnson!"
// نصوص متعددة الأسطر مع القوالب النصية
let poem = `الورود حمراء,
البنفسج أزرق,
JavaScript ممتعة,
وأنت كذلك.`;
// طول النص
console.log(firstName.length); // 5
// الوصول إلى الأحرف
console.log(firstName[0]); // "A"
console.log(firstName.charAt(2)); // "i"
// النصوص غير قابلة للتغيير
firstName[0] = 'B'; // هذا لا يغير النص
console.log(firstName); // لا يزال "Alice"
النصوص غير قابلة للتغيير في JavaScript. بمجرد إنشاء نص، لا يمكنك تغيير أحرف فردية فيه. أي عملية تبدو وكأنها تعدل النص تنشئ في الواقع نصا جديدا. هذا مفهوم مهم لأنه يؤثر على الأداء عند بناء نصوص كبيرة من خلال الدمج في حلقة -- فكر في استخدام مصفوفة وjoin() بدلا من ذلك.
نوع الرقم (Number)
تحتوي JavaScript على نوع number واحد يمثل الأعداد الصحيحة والأعداد العشرية معا. داخليا، يتم تخزين جميع الأرقام كقيم عشرية بدقة 64 بت (IEEE 754 مزدوجة الدقة). هذا يعني أن JavaScript يمكنها تمثيل الأعداد الصحيحة بدقة حتى 2^53 - 1 (أي 9,007,199,254,740,991) والأعداد العشرية مع بعض قيود الدقة المتأصلة.
مثال: العمل مع الأرقام
// قيم صحيحة
let age = 30;
let negative = -15;
let hex = 0xFF; // 255 بالنظام الست عشري
let octal = 0o77; // 63 بالنظام الثماني
let binary = 0b1010; // 10 بالنظام الثنائي
// قيم عشرية
let price = 19.99;
let scientific = 2.5e6; // 2,500,000
// قيم رقمية خاصة
let positiveInf = Infinity;
let negativeInf = -Infinity;
let notANumber = NaN;
// مشاكل دقة الأعداد العشرية
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false!
// نطاق الأعداد الصحيحة الآمنة
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
// فواصل رقمية لسهولة القراءة (ES2021)
let billion = 1_000_000_000;
let bytes = 0xFF_FF_FF;
console.log(billion); // 1000000000
0.1 + 0.2 !== 0.3) ليست خطأ في JavaScript -- إنها متأصلة في كيفية عمل أرقام IEEE 754 العشرية في جميع لغات البرمجة. عند مقارنة الأعداد العشرية، استخدم قيمة تسامح صغيرة (إبسيلون): Math.abs(a - b) < Number.EPSILON. للحسابات المالية، اعمل بالأعداد الصحيحة التي تمثل أصغر وحدة عملة (مثل القروش بدلا من الريالات).فهم NaN و Infinity
NaN تعني "ليس رقما" وتمثل نتيجة عملية رياضية غير محددة أو غير قابلة للتمثيل. رغم اسمها، فإن typeof NaN تعيد "number". أكثر خاصية مفاجئة لـ NaN هي أنها لا تساوي نفسها -- NaN === NaN تعيد false. هذه هي القيمة الوحيدة في JavaScript التي تملك هذه الخاصية.
مثال: سلوك NaN
// العمليات التي تنتج NaN
console.log(0 / 0); // NaN
console.log(parseInt('hello')); // NaN
console.log(Math.sqrt(-1)); // NaN
console.log(undefined + 1); // NaN
// NaN لا تساوي نفسها
console.log(NaN === NaN); // false
console.log(NaN == NaN); // false
// التحقق من NaN
console.log(isNaN('hello')); // true (يحول أولا ثم يتحقق)
console.log(Number.isNaN('hello')); // false (صارم، بدون تحويل)
console.log(Number.isNaN(NaN)); // true
// NaN معدية -- أي حساب مع NaN ينتج NaN
console.log(NaN + 5); // NaN
console.log(NaN * 100); // NaN
Number.isNaN() بدلا من دالة isNaN() العامة. دالة isNaN() العامة تحاول أولا تحويل وسيطها إلى رقم، مما يمكن أن ينتج نتائج مضللة. مثلا، isNaN('hello') تعيد true لأن 'hello' تتحول إلى NaN، لكن 'hello' هي نص وليست NaN. أما Number.isNaN() فتعيد true فقط عندما يكون الوسيط هو فعلا NaN.Infinity تمثل قيمة أكبر من أي رقم محدود. تنتج من قسمة رقم موجب على الصفر أو من التجاوز الرياضي. -Infinity هي نظيرتها السالبة. يمكنك التحقق من القيم المحدودة باستخدام isFinite() أو Number.isFinite().
مثال: Infinity
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Infinity + 100); // Infinity
console.log(Infinity - Infinity); // NaN
// التحقق من القيم المحدودة
console.log(Number.isFinite(42)); // true
console.log(Number.isFinite(Infinity)); // false
console.log(Number.isFinite(NaN)); // false
console.log(Number.isFinite('42')); // false (بدون تحويل)
نوع BigInt
تم تقديم BigInt في ES2020 لتمثيل الأعداد الصحيحة بدقة عشوائية. الأرقام العادية تفقد الدقة بعد Number.MAX_SAFE_INTEGER، لكن BigInt يمكنها التعامل مع أعداد صحيحة بأي حجم. تنشئ BigInt بإلحاق n بعد الرقم الصحيح أو باستدعاء BigInt().
مثال: BigInt
// إنشاء قيم BigInt
let big = 9007199254740993n;
let alsoBig = BigInt("9007199254740993");
// الرقم العادي يفقد الدقة
console.log(9007199254740993); // 9007199254740992 (خطأ!)
console.log(9007199254740993n); // 9007199254740993n (صحيح)
// حساب BigInt
console.log(100n + 200n); // 300n
console.log(100n * 100n); // 10000n
// لا يمكن مزج BigInt و Number
// console.log(100n + 50); // TypeError!
// يجب التحويل صراحة
console.log(100n + BigInt(50)); // 150n
console.log(Number(100n) + 50); // 150
// مقارنة BigInt مع Number تعمل
console.log(100n === 100); // false (أنواع مختلفة)
console.log(100n == 100); // true (مقارنة القيمة)
النوع المنطقي (Boolean)
القيم المنطقية تمثل القيم المنطقية: true أو false. هي أساس كل المنطق الشرطي في JavaScript. تنتج القيم المنطقية عادة من عمليات المقارنة والعوامل المنطقية، وتتحكم في تدفق برامجك من خلال عبارات if والحلقات والتعبيرات الثلاثية.
مثال: القيم المنطقية
let isLoggedIn = true;
let hasPermission = false;
// عمليات المقارنة تنتج قيما منطقية
console.log(5 > 3); // true
console.log(10 === 10); // true
console.log('a' < 'b'); // true (مقارنة معجمية)
// العمليات المنطقية مع القيم المنطقية
console.log(true && false); // false
console.log(true || false); // true
console.log(!true); // false
Undefined و Null
undefined وnull كلاهما يمثل غياب القيمة، لكن لهما معانٍ واستخدامات مختلفة. undefined يعني أن المتغير تم التصريح عنه لكن لم يتم تعيين قيمة له -- إنها حالة "لا قيمة" الافتراضية في JavaScript. null هو تعيين مقصود يعني "لا قيمة" أو "فارغ" -- المطور اختار صراحة تعيينها. فكر في undefined على أنها "لم يتم تعيينها بعد" وnull على أنها "فارغة عمدا".
مثال: الفرق بين Undefined و Null
// undefined -- متغير معرف لكن لم يتم تعيينه
let x;
console.log(x); // undefined
console.log(typeof x); // "undefined"
// دالة بدون قيمة إرجاع
function doNothing() {}
console.log(doNothing()); // undefined
// الوصول إلى خاصية غير موجودة
let obj = { name: 'Alice' };
console.log(obj.age); // undefined
// null -- غياب متعمد للقيمة
let user = null; // سيتم تعيين المستخدم لاحقا
console.log(user); // null
console.log(typeof null); // "object" (هذا خطأ معروف في JavaScript!)
// مقارنة undefined و null
console.log(undefined == null); // true (مساواة فضفاضة)
console.log(undefined === null); // false (مساواة صارمة)
// التحقق من null أو undefined
let value = null;
if (value == null) {
console.log('القيمة هي null أو undefined');
}
// هذا مكافئ لـ:
if (value === null || value === undefined) {
console.log('القيمة هي null أو undefined');
}
typeof null تعيد "object" بدلا من "null" هي خطأ معروف موجود منذ أول إصدار من JavaScript. لم يتم إصلاحه أبدا لأن ذلك سيكسر الكود الموجود عبر الويب. تحقق دائما من null باستخدام === null بدلا من الاعتماد على typeof.نوع الرمز (Symbol)
الرموز هي معرفات فريدة تم تقديمها في ES2015 (ES6). كل رمز مضمون أن يكون فريدا، حتى لو كان لرمزين نفس الوصف. تستخدم بشكل أساسي كمفاتيح خصائص لتجنب تعارض الأسماء ولإنشاء خصائص شبيهة بالخاصة على الكائنات.
مثال: الرموز
// إنشاء الرموز
let id = Symbol('id');
let anotherId = Symbol('id');
// كل رمز فريد
console.log(id === anotherId); // false
// استخدام الرموز كمفاتيح للكائنات
let user = {
name: 'Alice',
[id]: 12345
};
console.log(user[id]); // 12345
console.log(user.name); // "Alice"
// الرموز غير قابلة للتعداد في حلقات for...in
for (let key in user) {
console.log(key); // فقط "name" -- مفتاح الرمز مخفي
}
// سجل الرموز العالمي
let globalSym = Symbol.for('app.id');
let sameGlobalSym = Symbol.for('app.id');
console.log(globalSym === sameGlobalSym); // true
عامل typeof
عامل typeof يعيد نصا يشير إلى نوع القيمة. هو أداتك الأساسية للتحقق من الأنواع أثناء التشغيل. ومع ذلك، لديه بعض المفارقات التي تحتاج لمعرفتها، أبرزها أن typeof null تعيد "object" وأن typeof للدوال تعيد "function" رغم أن الدوال تقنيا هي كائنات.
مثال: نتائج typeof
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof 42n); // "bigint"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (خطأ!)
console.log(typeof Symbol('x')); // "symbol"
console.log(typeof {}); // "object"
console.log(typeof []); // "object" (المصفوفات هي كائنات)
console.log(typeof function(){}); // "function"
// التحقق العملي من الأنواع
function getType(value) {
if (value === null) return 'null';
if (Array.isArray(value)) return 'array';
return typeof value;
}
console.log(getType(null)); // "null"
console.log(getType([1,2,3])); // "array"
console.log(getType(42)); // "number"
تحويل الأنواع: ضمني مقابل صريح
تحويل الأنواع هو عملية تحويل قيمة من نوع إلى آخر. تقوم JavaScript بتحويل الأنواع بطريقتين: التحويل الضمني (تلقائي، تقوم به اللغة) والتحويل الصريح (مقصود، يقوم به المطور). التحويل الضمني هو أحد أكثر جوانب JavaScript إرباكا ومصدر متكرر للأخطاء، لذا فهمه بشكل شامل أمر ضروري.
التحويل الضمني (التلقائي)
تقوم JavaScript تلقائيا بتحويل الأنواع عندما تواجه عملية بين أنواع غير متوافقة. قواعد التحويل الضمني تعتمد على العامل والأنواع المعنية. المحفزات الأكثر شيوعا هي عامل + (الذي يمكن أن يعني الجمع أو دمج النصوص) وعوامل المقارنة والسياقات المنطقية (مثل عبارات if).
مثال: التحويل الضمني مع عامل +
// دمج النصوص يفوز عندما يكون أحد المعاملات نصا
console.log('5' + 3); // "53" (الرقم 3 يصبح "3")
console.log('5' + true); // "5true"
console.log('5' + null); // "5null"
console.log('5' + undefined); // "5undefined"
// العوامل الحسابية الأخرى تحول إلى أرقام
console.log('5' - 3); // 2
console.log('5' * 3); // 15
console.log('5' / 2); // 2.5
console.log('5' % 2); // 1
// نتائج مفاجئة
console.log('5' + 3 - 1); // 52 ("53" - 1 = 52)
console.log(5 + 3 + 'px'); // "8px"
console.log('px' + 5 + 3); // "px53"
// العامل الأحادي + يحول إلى رقم
console.log(+'42'); // 42
console.log(+''); // 0
console.log(+true); // 1
console.log(+false); // 0
console.log(+null); // 0
console.log(+undefined); // NaN
'5' + 3 ينتج "53" (نص) وليس 8 (رقم). عامل + يقوم بدمج النصوص كلما كان أحد المعاملات نصا. لكن '5' - 3 ينتج 2 (رقم) لأن عامل - يعمل فقط مع الأرقام ويفرض التحويل. هذا التناقض هو مصدر رئيسي للأخطاء. حوّل الأنواع صراحة دائما قبل العمليات الحسابية.التحويل الصريح (المقصود)
التحويل الصريح هو عندما تقوم عمدا بتحويل قيمة من نوع إلى آخر باستخدام الدوال المدمجة. هذا مفضل دائما على الاعتماد على التحويل الضمني لأنه يجعل نيتك واضحة وكودك أكثر قابلية للتنبؤ.
مثال: التحويلات الصريحة للأنواع
// التحويل إلى رقم
console.log(Number('42')); // 42
console.log(Number('')); // 0
console.log(Number('hello')); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
// parseInt و parseFloat
console.log(parseInt('42px')); // 42 (يتوقف عند الحرف غير الرقمي)
console.log(parseInt('0xFF', 16)); // 255
console.log(parseFloat('3.14m')); // 3.14
// التحويل إلى نص
console.log(String(42)); // "42"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
console.log(String(NaN)); // "NaN"
// طريقة .toString()
console.log((42).toString()); // "42"
console.log((255).toString(16)); // "ff" (ست عشري)
console.log((10).toString(2)); // "1010" (ثنائي)
// التحويل إلى قيمة منطقية
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean('hello')); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean({})); // true (الكائنات دائما صادقة)
console.log(Boolean([])); // true (حتى المصفوفات الفارغة!)
القيم الصادقة والكاذبة
في JavaScript، كل قيمة هي بطبيعتها إما "صادقة" (truthy) أو "كاذبة" (falsy). القيمة الكاذبة هي التي تصبح false عند تحويلها إلى قيمة منطقية. القيمة الصادقة تصبح true. هذا مهم لأن JavaScript تحول القيم تلقائيا إلى قيم منطقية في السياقات الشرطية مثل عبارات if والعوامل الثلاثية والعوامل المنطقية.
هناك بالضبط ثماني قيم كاذبة في JavaScript. كل شيء آخر صادق:
مثال: القيم الكاذبة (القائمة الكاملة)
// جميع القيم الكاذبة الثمانية
console.log(Boolean(false)); // false -- القيمة المنطقية false نفسها
console.log(Boolean(0)); // false -- الصفر
console.log(Boolean(-0)); // false -- الصفر السالب
console.log(Boolean(0n)); // false -- BigInt صفر
console.log(Boolean('')); // false -- النص الفارغ
console.log(Boolean(null)); // false -- null
console.log(Boolean(undefined)); // false -- undefined
console.log(Boolean(NaN)); // false -- ليس رقما
// كل شيء آخر صادق، بما في ذلك هذه المفاجآت:
console.log(Boolean('0')); // true (نص غير فارغ!)
console.log(Boolean('false')); // true (نص غير فارغ!)
console.log(Boolean([])); // true (مصفوفة فارغة!)
console.log(Boolean({})); // true (كائن فارغ!)
console.log(Boolean(function(){})); // true (دالة!)
!!) هو اختصار شائع لتحويل قيمة إلى قيمة منطقية. !!value مكافئ لـ Boolean(value). العلامة ! الأولى تحول إلى قيمة منطقية وتنفي، والثانية ! تنفي مرة أخرى. مثلا، !!'hello' تعيد true و!!0 تعيد false.مثال: الصادق/الكاذب في السياقات الشرطية
// استخدام الصادق/الكاذب في عبارات if
let username = '';
if (username) {
console.log(`مرحبا، ${username}`);
} else {
console.log('الرجاء إدخال اسمك'); // هذا يعمل
}
// نمط شائع: القيم الافتراضية مع ||
let input = '';
let name = input || 'مجهول';
console.log(name); // "مجهول"
// تحذير: || يعامل 0 و "" ككاذبة
let count = 0;
let result = count || 10;
console.log(result); // 10 (وليس 0!) -- على الأرجح ليس ما تريده
// أفضل: استخدم ?? (التحقق من القيمة العدمية) لـ 0 و ""
let betterResult = count ?? 10;
console.log(betterResult); // 0 -- فقط null/undefined يتم استبدالها
مخاطر المقارنة: == مقابل ===
تحتوي JavaScript على عاملي مساواة: المساواة الفضفاضة (==) والمساواة الصارمة (===). الفرق هو أن == تقوم بتحويل الأنواع قبل المقارنة، بينما === لا تفعل ذلك -- تتطلب تطابق القيمة والنوع معا. قواعد تحويل الأنواع في == معقدة وغير بديهية، ولهذا التوصية الغالبة هي استخدام === دائما.
مثال: مقارنة == مقابل ===
// المساواة الصارمة (===) -- بدون تحويل أنواع
console.log(5 === 5); // true
console.log(5 === '5'); // false (أنواع مختلفة)
console.log(0 === false); // false (أنواع مختلفة)
console.log('' === false); // false (أنواع مختلفة)
console.log(null === undefined); // false (أنواع مختلفة)
// المساواة الفضفاضة (==) -- تقوم بتحويل الأنواع
console.log(5 == '5'); // true (النص "5" يصبح الرقم 5)
console.log(0 == false); // true (false يصبح 0)
console.log('' == false); // true (كلاهما يصبح 0)
console.log(null == undefined); // true (قاعدة خاصة)
console.log(null == 0); // false (null تساوي undefined فقط)
// السلسلة المربكة مع ==
console.log('' == 0); // true
console.log(0 == false); // true
console.log('' == false); // true
// لكن!
console.log('' == null); // false (null تساوي undefined فقط ==)
// توليفات غريبة بين الصادق/الكاذب والمساواة
console.log([] == false); // true ([] تصبح ""، "" تصبح 0، false تصبح 0)
console.log([] == ![]); // true (! لها أسبقية أعلى)
console.log('' == []); // true
// استخدم === دائما
console.log(5 !== '5'); // true (عدم مساواة صارمة)
console.log(null !== undefined); // true
=== و!== للمقارنات. الاستثناء الشائع الوحيد هو التحقق من null أو undefined بـ value == null، الذي يلتقط كلا من null وundefined في تحقق واحد. هذا نمط مقبول حتى في قواعد الكود الصارمة لأن البديل (value === null || value === undefined) أكثر إسهابا بدون فائدة عملية.Object.is() -- المقارنة الأكثر صرامة
Object.is() مشابهة لـ === لكنها تتعامل مع حالتين حدوديتين بشكل مختلف: تعتبر NaN مساوية لـ NaN، وتميز بين +0 و-0. رغم أنك نادرا ما ستحتاجها، من المفيد معرفة وجودها لتلك الحالات الحدودية.
مثال: Object.is()
// Object.is() مقابل ===
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
// لجميع الحالات الأخرى، Object.is() تتصرف مثل ===
console.log(Object.is(5, 5)); // true
console.log(Object.is(5, '5')); // false
جدول ملخص تحويل الأنواع
إليك مرجع شامل لكيفية تحويل القيم المختلفة عبر الأنواع. فهم هذه التحويلات سيساعدك على التنبؤ بسلوك JavaScript وكتابة كود أكثر موثوقية:
مرجع: نتائج التحويل
// القيمة | Number() | String() | Boolean()
// ------------- | -------- | ------------- | ---------
// "" | 0 | "" | false
// "0" | 0 | "0" | true
// "42" | 42 | "42" | true
// "hello" | NaN | "hello" | true
// true | 1 | "true" | true
// false | 0 | "false" | false
// null | 0 | "null" | false
// undefined | NaN | "undefined" | false
// 0 | 0 | "0" | false
// 1 | 1 | "1" | true
// NaN | NaN | "NaN" | false
// Infinity | Infinity | "Infinity" | true
// [] | 0 | "" | true
// [1] | 1 | "1" | true
// {} | NaN | "[object Object]" | true
Number('') التي تعيد 0 وNumber(undefined) التي تعيد NaN. لاحظ أيضا أن Number(null) تعيد 0 بينما Number(undefined) تعيد NaN. هذه التناقضات هي من أكثر الفخاخ شيوعا في تحويل أنواع JavaScript.أنماط عملية لسلامة الأنواع
الآن بعد أن فهمت كيف تعمل الأنواع في JavaScript، إليك أنماط عملية يجب أن تتبناها في كودك لتجنب الأخطاء المتعلقة بالأنواع وكتابة برامج أكثر متانة.
مثال: أنماط التحقق الآمن من الأنواع
// تحليل رقمي آمن
function safeParseNumber(value) {
if (typeof value === 'number') return value;
if (typeof value !== 'string') return NaN;
let trimmed = value.trim();
if (trimmed === '') return NaN;
return Number(trimmed);
}
console.log(safeParseNumber('42')); // 42
console.log(safeParseNumber(' 42 ')); // 42
console.log(safeParseNumber('')); // NaN (وليس 0!)
console.log(safeParseNumber(null)); // NaN
// دالة مقارنة آمنة الأنواع
function isEqual(a, b) {
// معالجة حالة NaN
if (Number.isNaN(a) && Number.isNaN(b)) return true;
return a === b;
}
console.log(isEqual(NaN, NaN)); // true
console.log(isEqual(5, '5')); // false
// التحقق من null أو undefined
function isNullish(value) {
return value == null; // يلتقط كلا من null و undefined
}
console.log(isNullish(null)); // true
console.log(isNullish(undefined)); // true
console.log(isNullish(0)); // false
console.log(isNullish('')); // false
تمرين عملي
أنشئ دالة تسمى describeValue تأخذ أي قيمة وتعيد نصا يصف نوعها وخصائصها. يجب أن تقوم الدالة بـ: (1) إعادة "null" لقيم null بدلا من "object". (2) تحديد المصفوفات كـ "array" بدلا من "object". (3) الإبلاغ عما إذا كان الرقم هو NaN أو Infinity أو عدد صحيح آمن أو عدد عشري. (4) الإبلاغ عن طول النصوص. (5) الإبلاغ عما إذا كانت القيمة صادقة أم كاذبة. اختبر دالتك مع 10 قيم مختلفة على الأقل بما في ذلك الحالات الحدودية مثل NaN و0 والنص الفارغ والمصفوفة الفارغة وnull وundefined. ثم أنشئ دالة ثانية تسمى safeAdd تأخذ وسيطين وتعيد مجموعهما الرقمي مع معالجة جميع الحالات الحدودية: إذا لم يكن أي من الوسيطين قابلا للتحويل إلى رقم صالح، أعد 0 بدلا من NaN. اختبرها مع النصوص والقيم المنطقية و null و undefined والأرقام الفعلية.