المتغيرات في لغة JavaScript


يا هلا بالشباب! اليوم بنتكلم عن حاجة أساسية جداً في أي لغة برمجة، وهي المتغيرات (Variables). في JavaScript، المتغيرات هي زي الأوعية اللي نحط فيها بيانات عشان نقدر نستخدمها ونغيرها وقت ما نحتاج.

ليش نحتاج المتغيرات؟

تخيل إنك قاعد تكتب برنامج بسيط يحسب مجموع عددين. بدل ما تكتب الأعداد مباشرة في كل عملية حسابية، الأفضل إنك تحطها في متغيرات. كذا لو بغيت تغير الأعداد، تغيرها في مكان واحد بس. وكمان، تخيل لو عندك اسم مستخدم، أفضل تحطه في متغير userName عشان تقدر تستخدمه في أماكن كثيرة من الكود.

أنواع تعريف المتغيرات في JavaScript

في JavaScript، عندنا 3 كلمات مفتاحية (keywords) عشان نعرف المتغيرات:

  • var (القديم شوي)
  • let (الأفضل للاستخدام العام)
  • const (للثوابت اللي ما تتغير)

1. المتغيرات باستخدام var

هذي الطريقة كانت الأساسية قبل ES6 (إصدار 2015). لها كم ميزة وكم مشكلة:

  • نطاق الدالة (Function Scope): يعني المتغير اللي تعرفه بـ var داخل دالة، ما تقدر تستخدمه إلا داخل هذي الدالة. لو عرفته برا أي دالة، يكون نطاقه عام (Global Scope).
  • الرفع (Hoisting): المتغيرات اللي تعرفها بـ var يتم "رفعها" لأعلى نطاقها. يعني تقدر تستخدم المتغير قبل ما تعرفه، بس قيمته بتكون undefined إلى أن يتم تعيينها.
  • إعادة التعريف (Re-declaration): تقدر تعيد تعريف نفس المتغير بـ var أكثر من مرة بدون مشاكل، وهذا ممكن يسبب أخطاء غير متوقعة.

مثال:

var x = 10;
console.log(x); // 10

function exampleVar() {
    var y = 20;
    console.log(y); // 20
}
exampleVar();
// console.log(y); // ReferenceError: y is not defined (because of function scope)

var x = 30; // عادي، ممكن تعيد تعريفها
console.log(x); // 30

console.log(z); // undefined (hoisted)
var z = 50;
console.log(z); // 50

ملاحظة: عموماً، يفضل عدم استخدام var في المشاريع الجديدة بسبب المشاكل اللي ممكن تسببها مثل الـ hoisting وإعادة التعريف.

2. المتغيرات باستخدام let

let تم تقديمها في ES6 وهي أفضل بديل لـ var في معظم الحالات. أهم ميزاتها:

  • نطاق الكتلة (Block Scope): يعني المتغير اللي تعرفه بـ let داخل أي كتلة (مثل داخل if أو for loop أو حتى أقواس {} عادية)، ما تقدر تستخدمه إلا داخل هذي الكتلة.
  • لا يوجد رفع كامل (No Hoisting - Temporal Dead Zone): على عكس var، المتغيرات المعرفة بـ let لا يتم رفعها بشكل كامل. لو حاولت تستخدمها قبل تعريفها، بيعطيك خطأ ReferenceError.
  • لا يمكن إعادة تعريفها في نفس النطاق: ما تقدر تعيد تعريف نفس المتغير بـ let في نفس النطاق، وهذا يقلل من الأخطاء.

مثال:

let a = 10;
console.log(a); // 10

if (true) {
    let b = 20;
    console.log(b); // 20
}
// console.log(b); // ReferenceError: b is not defined (because of block scope)

// let a = 30; // SyntaxError: Identifier 'a' has already been declared (لا يمكن إعادة تعريفها)

// console.log(c); // ReferenceError: Cannot access 'c' before initialization (Temporal Dead Zone)
let c = 50;
console.log(c); // 50

3. المتغيرات باستخدام const

const أيضاً تم تقديمها في ES6 وهي اختصار لكلمة "constant" (ثابت). تستخدم لتعريف المتغيرات اللي قيمتها ما تتغير أبداً بعد تعريفها الأول.

  • نطاق الكتلة (Block Scope): مثل let.
  • لا يوجد رفع كامل (No Hoisting - Temporal Dead Zone): مثل let.
  • يجب تهيئتها عند التعريف: لازم تعطيها قيمة أول ما تعرفها.
  • لا يمكن إعادة تعيين قيمتها: بعد ما تعطيها قيمة، ما تقدر تغيرها أبداً.

مثال:

const PI = 3.14;
console.log(PI); // 3.14

// PI = 3.14159; // TypeError: Assignment to constant variable. (لا يمكن إعادة تعيينها)

// const GRAVITY; // SyntaxError: Missing initializer in const declaration (يجب تهيئتها)

if (true) {
    const MY_NAME = "Ali";
    console.log(MY_NAME); // Ali
}
// console.log(MY_NAME); // ReferenceError: MY_NAME is not defined (because of block scope)

ملاحظة هامة بخصوص const مع الكائنات (Objects) والمصفوفات (Arrays):
لما تعرف كائن أو مصفوفة بـ const، هذا يعني إنك ما تقدر تعيد تعيين المتغير نفسه لكائن أو مصفوفة جديدة. لكن تقدر تغير المحتوى الداخلي للكائن أو المصفوفة. يعني تقدر تضيف أو تحذف عناصر من مصفوفة، أو تغير خصائص كائن.

const user = { name: "Ahmed", age: 30 };
user.age = 31; // هذا مسموح!
console.log(user); // { name: "Ahmed", age: 31 }

// user = { name: "Khaled", age: 25 }; // هذا غير مسموح! TypeError

const numbers = [1, 2, 3];
numbers.push(4); // هذا مسموح!
console.log(numbers); // [1, 2, 3, 4]

// numbers = [5, 6]; // هذا غير مسموح! TypeError

أفضل الممارسات (Best Practices)

في المشاريع الحديثة، القاعدة الذهبية هي:

  • استخدم const دائماً إذا كنت متأكد إن قيمة المتغير ما راح تتغير.
  • إذا كنت تتوقع إن قيمة المتغير ممكن تتغير، استخدم let.
  • تجنب استخدام var قدر الإمكان عشان تتفادى المشاكل المحتملة.

وبكذا نكون غطينا أساسيات المتغيرات في JavaScript. ركز على let و const، وراح تكون أمورك تمام.