Menu
العربية
جرّب في Playground

الأنواع البدائية في JavaScript: القيم السبع الأساسية

تعرّف على الأنواع البدائية السبعة في JavaScript — string و number و bigint و boolean و null و undefined و symbol — والفرق بينها وبين الكائنات.

الأنواع البدائية في JavaScript: سبعة أنواع وما عداها

تُقسِّم JavaScript القيم إلى فئتين. الأولى تضم سبعة أنواع بدائية (primitive types) — قيم بسيطة وغير قابلة للتغيير. والثانية هي الكائنات (objects) — وتشمل كل ما هو مُركَّب أو قابل للتغيير أو قابل للاستدعاء. هذا هو نظام الأنواع في JavaScript على مستوى القيم، باختصار.

الأنواع البدائية السبعة هي:

index.js
Output
Click Run to see the output here.

أي شيء خارج هذه القائمة — المصفوفات، الدوال، التواريخ، التعابير النمطية، وحتى {} العادي — يُعتبر كائنًا (object). العامل typeof يكشف لك النوع أثناء التشغيل، وستلاحظ في السطر الأخير العيب الشهير: typeof null يُرجع 'object' منذ عام 1995، ولن يُصلَح أبدًا لأن شيفرات كثيرة قائمة تعتمد على هذا السلوك.

القيمة البدائية هي القيمة نفسها، وليست وعاءً لها

أفضل تصوّر ذهني يساعدك على فهم الأنواع البدائية في JavaScript هو التالي: القيمة البدائية هي قيمتها بحد ذاتها. الرقم 3 ليس صندوقًا يحتوي على 3، بل هو ببساطة 3. ومتغيّران يحملان 3 يحملان القيمة ذاتها، لا نسختين تشيران إلى شيء مشترك:

index.js
Output
Click Run to see the output here.

تتم مقارنة القيم البدائية بالقيمة نفسها، بينما تُقارَن الكائنات بالمرجع. هذا الفرق الصغير هو السبب وراء كثير من لحظات الحيرة من نوع "لماذا النتيجة false؟" التي ستواجهها لاحقًا، خاصة عند مقارنة المصفوفات أو الكائنات باستخدام ===.

الأنواع البدائية في JavaScript غير قابلة للتعديل

لا يمكنك تعديل قيمة بدائية. أي عملية تبدو وكأنها تغيّر القيمة، هي في الحقيقة تُنتج قيمة جديدة:

index.js
Output
Click Run to see the output here.

الاستدعاء الأول يُنشئ سلسلة نصية جديدة ثم يرميها في القمامة لأن لا أحد التقط القيمة المُرجَعة. أما الاستدعاء الثاني فيُعيد إسناد قيمة جديدة إلى name. السلسلة الأصلية "ada" لم تتغيّر أبداً، ولا يمكن أن تتغيّر أصلاً. والأمر نفسه ينطبق على الأرقام: x + 1 يُنتج رقماً جديداً، ولا يُعدِّل x.

لهذا السبب استخدام const مع السلاسل النصية والأرقام آمن فعلاً؛ فالقيمة لا يمكن أن تتغيّر، و const يمنعك من إعادة إسناد المتغيّر.

الأعداد و BigInt ولماذا يوجد نوعان؟

النوع number في JavaScript هو عدد عشري بدقة 64-bit. هذا يعني عمليات حسابية سريعة، لكن مع سقف محدود: الأعداد الصحيحة تكون دقيقة فقط حتى Number.MAX_SAFE_INTEGER (أي 2^53 - 1):

index.js
Output
Click Run to see the output here.

ما إن تتجاوز هذه العتبة حتى تبدأ الأعداد الصحيحة في التصادم فيما بينها. ولهذا وُجد النوع bigint، فهو مخصّص للأعداد الصحيحة التي يجب أن تبقى دقيقة مهما كبر حجمها. ولتعريف قيمة من هذا النوع، ما عليك سوى إلحاق الحرف n بنهاية الرقم:

index.js
Output
Click Run to see the output here.

لا يمكنك خلط bigint مع number في العمليات الحسابية — لأن ذلك يُفقد الدقة الإضافية كل قيمتها. استخدم bigint عند التعامل مع معرّفات قواعد البيانات، أو الطوابع الزمنية بدقة النانو ثانية، أو في عمليات التشفير. أمّا الحسابات العادية فتبقى من نصيب number.

السلاسل النصية أنواع بدائية أيضًا

السلسلة النصية في JavaScript نوع بدائي (primitive) وليست كائنًا، رغم أنها تُتيح لك استدعاء توابع مثل .length و .slice و .toUpperCase:

index.js
Output
Click Run to see the output here.

خلف الكواليس، عندما تستدعي ميثود على سلسلة نصية، يقوم JavaScript بتغليفها مؤقتًا داخل كائن String حتى يعمل استدعاء الميثود، ثم يتخلص من الغلاف مباشرةً. لا داعي للتفكير في هذا الغلاف — يكفي أن تعرف أن السلاسل النصية تتصرف كقيم (غير قابلة للتعديل، وتُقارَن بالقيمة) رغم امتلاكها مجموعة غنية من الميثودز.

علامات الاقتباس المفردة والمزدوجة والـ backticks كلها تُنشئ النوع نفسه. الفرق أن الـ backticks تدعم أيضًا الإقحام (interpolation) والسلاسل متعددة الأسطر، وهذا ما سنتناوله في الدرس التالي.

الفرق بين null و undefined في JavaScript

هناك نوعان بدائيان يعنيان "لا توجد قيمة"، وهما ليسا قابلَين للتبادل فيما بينهما.

القيمة undefined هي ما تحصل عليه عندما لا يتم إسناد شيء أصلًا — متغير مُعرَّف لكن بدون قيمة، أو وسيط دالة مفقود، أو خاصية غير موجودة:

index.js
Output
Click Run to see the output here.

null هي القيمة التي تكتبها أنت بنفسك حين تريد أن تقول "فارغ عن قصد":

index.js
Output
Click Run to see the output here.

الاتفاق الشائع بين المطورين: undefined هي طريقة اللغة نفسها لتقول "لا يوجد شيء هنا"، بينما null هي طريقة المبرمج ليعبّر عن الفراغ صراحةً. كلاهما قيم زائفة (falsy)، وكلاهما يفشل في المساواة مع القيم العادية، ولكلٍّ منهما صفحة مستقلة لاحقًا نغوص فيها بالتفاصيل.

النوع Symbol: قيم فريدة بحكم التعريف

يُعدّ symbol أقلّ الأنواع البدائية استخدامًا في JavaScript. كل رمز (symbol) تُنشئه يكون فريدًا تمامًا، حتى لو أنشأت رمزَين بالوصف نفسه:

index.js
Output
Click Run to see the output here.

الرموز (Symbols) مفيدة كمفاتيح للكائنات بحيث لا تتعارض مع مفاتيح موجودة مسبقًا — فمثلًا أي مكتبة خارجية تستطيع إرفاق بيانات وصفية بكائناتك عبر رمز (symbol)، وتكون متأكدة تمامًا أن لا كود آخر سيدهس هذه البيانات. وستصادفها مجددًا عند الحديث عن المُكرِّرات (iterators) والرموز المعروفة مثل Symbol.iterator.

فحص الأنواع وقت التشغيل باستخدام typeof في JavaScript

المُعامل typeof يغطي معظم الحالات، لكن انتبه إلى هذه الخصوصيات:

index.js
Output
Click Run to see the output here.

للتحقق من null، استخدم المقارنة المباشرة: value === null. وللمصفوفات، استعن بـ Array.isArray(value). أما إذا أردت معرفة ما إذا كانت القيمة من الأنواع البدائية بشكل عام، فلا توجد دالة جاهزة واحدة لذلك، لكن الصيغة المتعارف عليها واضحة بما يكفي:

index.js
Output
Click Run to see the output here.

الفرق بين الـ Primitives والـ Objects: فخّ الإسناد

في نقطة أخيرة تستحق الوقوف عندها قبل أن نكمل. لأن الأنواع البدائية (primitives) عبارة عن قيم، بينما الكائنات (objects) عبارة عن مراجع، فإن عملية الإسناد تتصرف بشكل مختلف بين الاثنين:

index.js
Output
Click Run to see the output here.

مع القيم البدائية، b = a تنسخ القيمة نفسها. أما مع الكائنات، فإن y = x تنسخ المرجع فقط — كلا الاسمين يشيران إلى نفس الكائن الموجود في الذاكرة. أي تعديل عبر أحد الاسمين ينعكس على الآخر. وهذا هو السبب الأول والأكبر لأخطاء من نوع "لحظة، لماذا تغيّرت هذه القيمة؟" في JavaScript.

خلاصة الدرس

  • هناك سبعة أنواع بدائية: string، number، bigint، boolean، null، undefined، symbol. وكل ما عدا ذلك يُعتبر كائنًا (object).
  • الأنواع البدائية غير قابلة للتغيير (immutable) وتُقارَن بالقيمة، بينما الكائنات قابلة للتغيير وتُقارَن بالمرجع.
  • عامل typeof يكشف لك النوع أثناء التشغيل، مع حالتين شاذتين يجدر حفظهما: typeof null === "object" وtypeof function === "function".
  • النوع number هو عدد عشري بدقة 64-bit وله سقف آمن للأعداد الصحيحة، وعند تجاوز هذا السقف يأتي دور bigint للتعامل مع الأعداد الصحيحة بدقة تامة.

التالي: النصوص والـ Template Literals

النصوص (strings) هي النوع البدائي الذي ستتعامل معه أكثر من غيره، وتأتي الـ template literals (تلك النصوص المحاطة بعلامات backtick) لتجعل بناءها أمرًا سهلًا — من الإقحام (interpolation)، إلى النصوص متعددة الأسطر، وصولًا إلى الـ tagged templates. هذا ما سنتناوله في الصفحة التالية.

الأسئلة الشائعة

كم عدد الأنواع البدائية في JavaScript؟

سبعة أنواع: string و number و bigint و boolean و null و undefined و symbol. أي شيء آخر — المصفوفات، الدوال، التواريخ، الكائنات العادية — يُعتبر كائنًا (object). يمكنك فحص نوع أي قيمة أثناء التشغيل باستخدام typeof، مع ملاحظة شاذّة تاريخية واحدة: typeof null تُرجع 'object'.

ما الفرق بين القيمة البدائية والكائن في JavaScript؟

القيم البدائية غير قابلة للتغيير (immutable) وتُقارَن بالقيمة — الرقمان 3 و 3 متساويان فعلًا. أما الكائنات فقابلة للتغيير وتُقارَن بالمرجع (reference)، لذا {} و {} مختلفان حتى لو بدَوا متطابقين. عند إسناد قيمة بدائية يتم نسخ القيمة نفسها، بينما عند إسناد كائن يتم نسخ المرجع الذي يشير إلى نفس البيانات.

هل الأنواع البدائية في JavaScript غير قابلة للتغيير فعلًا؟

نعم. لا يمكنك تعديل قيمة بدائية في مكانها — فاستدعاء 'hello'.toUpperCase() يُنتج سلسلة نصية جديدة ولا يُغيّر الأصلية. وعند إعادة الإسناد مثل x = x + 1 فأنت ببساطة تستبدل قيمة المتغيّر بقيمة بدائية أخرى، دون المساس بالقيمة القديمة. لهذا السبب يظل بإمكانك تكوين سلاسل جديدة من name رغم تعريفها بـ const name = 'Ada'.

لماذا يُرجع typeof null القيمة 'object'؟

هذا خطأ قديم في التنفيذ الأصلي للغة عام 1995، ولم يُصلَح لأن كودًا كثيرًا كان يعتمد على هذا السلوك. للتحقق من null استخدم المقارنة الصارمة: value === null. وللتحقق من undefined استخدم value === undefined أو typeof value === 'undefined'.

تعلّم البرمجة مع Coddy

ابدأ الآن