المتغيرات والأنواع
أساسيات المتغيرات الحديثة
JavaScript الحديثة: المتغيرات والأنواع وهياكل البيانات
في هذا الدرس سنستكشف أساسيات JavaScript الحديثة: كيفية التصريح عن المتغيرات، وفهم أنواع البيانات المختلفة، والتعامل مع العوامل، واستخدام هياكل البيانات الأساسية.
JavaScript لغة ديناميكية ومرنة تطورت كثيرًا منذ نشأتها. ومع ظهور ES6 (ECMAScript 2015) والإصدارات التي تلتها، أصبحت اللغة توفر ميزات قوية وحديثة.
التصريح عن المتغيرات
في JavaScript الحديثة، توجد ثلاث طرق للتصريح عن المتغيرات:
let
تتيح لك let التصريح عن متغيرات يقتصر نطاقها على الكتلة (block) التي عُرّفت فيها:
let age = 25;
age = 26; // إعادة الإسناد ممكنة
if (true) {
let message = "Hello"; // متغير محصور في هذه الكتلة
console.log(message); // "Hello"
}
// console.log(message); // خطأ: message غير معرّف
const
تتيح const التصريح عن ثوابت لا يمكن إعادة إسناد قيمتها:
const PI = 3.14159;
// PI = 3.14; // خطأ: لا يمكن إعادة إسناد ثابت
const personne = { nom: "Alice" };
personne.nom = "Bob"; // ممكن - المحتوى هو الذي يمكن أن يتغير
// personne = {}; // خطأ: لا يمكن إعادة إسناد المرجع
var (الطريقة القديمة)
كانت var الطريقة الوحيدة للتصريح عن المتغيرات قبل ES6. نطاقها محصور في الدالة أو عام:
var x = 10;
var x = 20; // إعادة التصريح ممكنة (وهذا إشكالي)
if (true) {
var y = 30; // النطاق غير محصور في الكتلة
}
console.log(y); // 30 - يمكن الوصول إلى y هنا
أفضل الممارسات
في JavaScript الحديثة، يُفضَّل ما يلي:
- استخدام
constافتراضيًا لكل متغير لن تُعاد إسناد قيمته - استخدام
letعندما تكون إعادة الإسناد ضرورية - تجنّب
varإلا إذا كنت تعمل مع شيفرة قديمة (legacy)
أنواع البيانات
JavaScript لغة ذات كتابة ديناميكية (dynamic typing)، مما يعني أنك لست بحاجة إلى تحديد نوع المتغير عند التصريح عنه.
الأنواع الأولية (Primitive)
1. Number
تستخدم JavaScript نوعًا واحدًا لجميع الأعداد:
const entier = 42;
const decimal = 3.14;
const exponentiel = 2.5e5; // 250000
const binaire = 0b1010; // 10
const octal = 0o744; // 484
const hexadecimal = 0xFF; // 255
// قيم خاصة
const infini = Infinity;
const pasUnNombre = NaN; // Not a Number
// عمليات التحقق
console.log(isNaN(pasUnNombre)); // true
console.log(isFinite(infini)); // false
2. String (السلسلة النصية)
توفر JavaScript عدة طرق لإنشاء السلاسل النصية:
// علامات اقتباس مفردة
const prenom = 'Marie';
// علامات اقتباس مزدوجة
const nom = "Dupont";
// Template literals (backticks) - ES6
const age = 30;
const message = `${prenom} ${nom} a ${age} ans.`;
// دوال مفيدة
console.log(prenom.toUpperCase()); // MARIE
console.log(" texte ".trim()); // "texte"
console.log("abc,def".split(",")); // ["abc", "def"]
console.log("Hello".includes("ell")); // true
3. Boolean
const estMajeur = true;
const estInscrit = false;
// تعبيرات شرطية
const a = 5;
const b = 10;
console.log(a < b); // true
console.log(a === b); // false (مساواة صارمة)
console.log(a >= 5); // true
4. Undefined
تمثل undefined متغيرًا مصرَّحًا عنه دون إسناد قيمة له:
let resultat;
console.log(resultat); // undefined
// التحقق
console.log(typeof resultat === 'undefined'); // true
5. Null
تمثل null غياب القيمة المتعمَّد:
const donnees = null;
// انتبه لهذا الفخ
console.log(typeof null); // "object" (خطأ تاريخي في JavaScript)
console.log(donnees === null); // true (استخدم المساواة الصارمة)
6. Symbol (ES6)
تنشئ Symbol معرّفات فريدة وغير قابلة للتغيير:
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // false - كل Symbol فريد
7. BigInt (ES2020)
لتمثيل أعداد صحيحة ذات حجم اعتباطي:
const grandNombre = 1234567890123456789012345678901234567890n;
const autreFacon = BigInt("9007199254740991");
console.log(typeof grandNombre); // "bigint"
الأنواع المرجعية (الكائنات)
1. Object
الكائنات هي مجموعات من أزواج المفتاح-القيمة:
// إنشاء كائن حرفي (literal)
const personne = {
prenom: "Jean",
nom: "Dupont",
age: 30,
adresse: {
ville: "Paris",
codePostal: "75001"
}
};
// الوصول إلى الخصائص
console.log(personne.prenom); // "Jean"
console.log(personne["nom"]); // "Dupont"
// إضافة/تعديل الخصائص
personne.email = "jean.dupont@example.com";
personne.age = 31;
// دوال الكائنات
const cles = Object.keys(personne); // ["prenom", "nom", "age", "adresse", "email"]
const valeurs = Object.values(personne); // ["Jean", "Dupont", 31, {...}, "jean..."]
2. Array
المصفوفات هي مجموعات مرتبة من القيم:
// إنشاء مصفوفة
const fruits = ["pomme", "banane", "cerise"];
const mixte = [1, "deux", true, null, { clé: "valeur" }];
// الوصول إلى العناصر (الفهرسة تبدأ من 0)
console.log(fruits[0]); // "pomme"
// دوال مفيدة
fruits.push("orange"); // تضيف في النهاية
fruits.pop(); // تحذف العنصر الأخير
fruits.unshift("fraise"); // تضيف في البداية
fruits.shift(); // تحذف العنصر الأول
// حلقة forEach
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// دوال التحويل (لا تعدّل المصفوفة الأصلية)
const fruitsMajuscules = fruits.map(fruit => fruit.toUpperCase());
const fruitsCourts = fruits.filter(fruit => fruit.length < 6);
const total = [1, 2, 3, 4].reduce((acc, val) => acc + val, 0); // 10
3. Function
في JavaScript، الدوال كائنات من الدرجة الأولى (first-class):
// تصريح الدالة
function saluer(nom) {
return `Bonjour, ${nom} !`;
}
// تعبير الدالة
const direAuRevoir = function(nom) {
return `Au revoir, ${nom} !`;
};
// الدالة السهمية (ES6)
const multiplier = (a, b) => a * b;
// دالة كمعامل
function executerFonction(fn, valeur) {
return fn(valeur);
}
console.log(executerFonction(saluer, "Marie")); // "Bonjour, Marie !"
4. Date
const maintenant = new Date();
const dateSpecifique = new Date("2023-12-31T23:59:59");
const timestamp = dateSpecifique.getTime(); // بالميلي ثانية منذ 1 يناير 1970
5. Map و Set (ES6)
// Map - مجموعة من أزواج المفتاح-القيمة (مفاتيحها من أي نوع)
const utilisateurs = new Map();
utilisateurs.set('u1', { nom: "Alice", age: 25 });
utilisateurs.set('u2', { nom: "Bob", age: 30 });
// Set - مجموعة من القيم الفريدة
const nombres = new Set([1, 2, 3, 3, 4, 4, 5]); // {1, 2, 3, 4, 5}
التحقق من الأنواع
للتحقق من نوع متغير، استخدم العامل typeof:
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof { a: 1 }); // "object"
console.log(typeof [1, 2, 3]); // "object" (المصفوفات كائنات في JS)
console.log(typeof function() {}); // "function"
وللتحقق من المصفوفات، استخدم Array.isArray():
console.log(Array.isArray([1, 2, 3])); // true
تحويل الأنواع
كثيرًا ما تجري JavaScript تحويلات ضمنية، لكن يمكنك أيضًا إجراؤها بشكل صريح:
// التحويل إلى سلسلة نصية
const num = 42;
const numStr = String(num); // "42"
const autreMethode = num.toString(); // "42"
// التحويل إلى عدد
const str = "42";
const strNum = Number(str); // 42
const parseMethode = parseInt(str, 10); // 42 (الأساس 10)
const parseFloat = parseFloat("3.14"); // 3.14
// التحويل إلى قيمة منطقية
const valeurBool = Boolean(1); // true
// false بالنسبة إلى: 0, "", null, undefined, NaN, false
العوامل
العوامل الحسابية
const a = 10;
const b = 3;
const addition = a + b; // 13
const soustraction = a - b; // 7
const multiplication = a * b; // 30
const division = a / b; // 3.3333...
const modulo = a % b; // 1 (باقي القسمة)
const puissance = a ** b; // 1000 (ES2016)
// الزيادة والإنقاص
let compteur = 0;
compteur++; // compteur = 1
compteur--; // compteur = 0
عوامل المقارنة
const a = 10;
const b = "10";
// المساواة (مع تحويل النوع)
console.log(a == b); // true
// المساواة الصارمة (دون تحويل)
console.log(a === b); // false
// عدم المساواة (مع تحويل)
console.log(a != b); // false
// عدم المساواة الصارمة (دون تحويل)
console.log(a !== b); // true
// المقارنات
console.log(a > 5); // true
console.log(a <= 10); // true
العوامل المنطقية
const x = true;
const y = false;
// AND المنطقي
console.log(x && y); // false
// OR المنطقي
console.log(x || y); // true
// NOT المنطقي
console.log(!x); // false
// الدارة المختصرة (short-circuit) (مفيدة للقيم الافتراضية)
const nom = null;
const nomAffiche = nom || "Utilisateur inconnu"; // "Utilisateur inconnu"
عامل الدمج الصفري (ES2020)
const valeur = null;
const resultat = valeur ?? "Valeur par défaut"; // "Valeur par défaut"
// يختلف عن || لأنه لا يستخدم القيمة الافتراضية إلا إذا كانت القيمة null أو undefined
عامل التسلسل الاختياري (ES2020)
const utilisateur = {
profil: {
// adresse: { ville: "Paris" }
}
};
// دون التسلسل الاختياري (خطر حدوث خطأ)
// const ville = utilisateur.profil.adresse.ville; // خطأ!
// مع التسلسل الاختياري
const ville = utilisateur.profil?.adresse?.ville; // undefined
عامل الانتشار (spread)
// بالنسبة إلى المصفوفات
const tab1 = [1, 2, 3];
const tab2 = [...tab1, 4, 5]; // [1, 2, 3, 4, 5]
// بالنسبة إلى الكائنات
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
التفكيك (Destructuring) (ES6)
يتيح التفكيك استخراج القيم من المصفوفات أو الكائنات بطريقة موجزة:
// تفكيك المصفوفة
const nombres = [1, 2, 3, 4, 5];
const [premier, deuxieme, ...reste] = nombres;
console.log(premier); // 1
console.log(deuxieme); // 2
console.log(reste); // [3, 4, 5]
// تفكيك الكائن
const personne = { prenom: "Alice", nom: "Dupont", age: 30 };
const { prenom, age, profession = "Inconnue" } = personne;
console.log(prenom); // "Alice"
console.log(age); // 30
console.log(profession); // "Inconnue" (قيمة افتراضية)
// إعادة تسمية الخصائص
const { prenom: firstName } = personne;
console.log(firstName); // "Alice"
// التفكيك المتداخل
const utilisateur = {
id: 1,
infos: {
nom: "Durand",
contact: {
email: "durand@example.com"
}
}
};
const { infos: { contact: { email } } } = utilisateur;
console.log(email); // "durand@example.com"
هياكل التحكم
توفر JavaScript هياكل التحكم المعتادة مع بعض الخصائص الحديثة.
الشروط
// if, else if, else
const age = 18;
if (age < 18) {
console.log("Mineur");
} else if (age === 18) {
console.log("Tout juste majeur");
} else {
console.log("Majeur");
}
// العامل الثلاثي
const statut = age >= 18 ? "majeur" : "mineur";
الحلقات
// for الكلاسيكية
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (للتكرار على قيم كائن قابل للتكرار)
const fruits = ["pomme", "banane", "cerise"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in (للتكرار على خصائص كائن)
const personne = { nom: "Dupont", prenom: "Jean", age: 30 };
for (const prop in personne) {
console.log(`${prop}: ${personne[prop]}`);
}
// while
let compteur = 0;
while (compteur < 5) {
console.log(compteur);
compteur++;
}
// do...while
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
Switch
const jour = "Lundi";
switch (jour) {
case "Lundi":
console.log("Début de semaine");
break;
case "Mercredi":
console.log("Milieu de semaine");
break;
case "Vendredi":
console.log("Fin de semaine");
break;
default:
console.log("Autre jour");
}
المدخلات والمخرجات الأساسية
وحدة التحكم (Console)
// العرض
console.log("Message simple");
console.info("Information");
console.warn("Avertissement");
console.error("Erreur");
// عرض منسّق
console.log("Nom: %s, Âge: %d", "Alice", 30);
// التجميع
console.group("Détails utilisateur");
console.log("Nom: Alice");
console.log("Âge: 30");
console.groupEnd();
// جدول
console.table([
{ nom: "Alice", age: 25 },
{ nom: "Bob", age: 30 }
]);
// قياس الوقت
console.time("Timer");
// عمليات طويلة...
console.timeEnd("Timer"); // يعرض الوقت المنقضي
التفاعل مع المستخدم (المتصفح)
// عرض رسالة
alert("Attention !");
// طلب تأكيد
const confirmation = confirm("Êtes-vous sûr ?");
if (confirmation) {
console.log("L'utilisateur a confirmé");
}
// طلب إدخال
const nom = prompt("Quel est votre nom ?", "Utilisateur");
console.log(`Bonjour, ${nom}`);
مثال كامل
إليك مثالًا يستخدم عدة مفاهيم تعلمناها:
// Programme qui calcule la moyenne d'une liste de nombres
// Définition d'une fonction fléchée pour calculer la moyenne
const calculerMoyenne = (nombres) => {
if (nombres.length === 0) return 0;
const somme = nombres.reduce((acc, val) => acc + val, 0);
return somme / nombres.length;
};
// Fonction pour comparer un nombre à la moyenne
const comparerAvecMoyenne = (nombre, moyenne) => {
if (nombre > moyenne) return "supérieur à";
if (nombre < moyenne) return "inférieur à";
return "égal à";
};
// Programme principal
try {
// Dans un environnement réel, ces valeurs pourraient venir d'une interface utilisateur
const nombres = [15, 20, 25, 10, 30];
// Afficher les nombres
console.log("Nombres:", nombres.join(", "));
// Calculer et afficher la moyenne
const moyenne = calculerMoyenne(nombres);
console.log(`La moyenne est: ${moyenne.toFixed(2)}`);
// Comparer chaque nombre à la moyenne
console.log("\nComparaison avec la moyenne:");
nombres.forEach((nombre, index) => {
const relation = comparerAvecMoyenne(nombre, moyenne);
console.log(`Nombre ${index + 1} (${nombre}) est ${relation} la moyenne.`);
});
// Filtrer les nombres supérieurs à la moyenne
const nombresSuperieurs = nombres.filter(nombre => nombre > moyenne);
console.log(`\nNombres supérieurs à la moyenne: ${nombresSuperieurs.join(", ")}`);
} catch (erreur) {
console.error("Une erreur est survenue:", erreur.message);
}
الاختلافات الرئيسية مع اللغات الأخرى
إذا كنتم تعرفون لغات برمجة أخرى، فإليكم بعض الاختلافات الملحوظة في JavaScript:
-
الكتابة الديناميكية (Dynamic typing): لا حاجة إلى التصريح بالأنواع، إذ يتم تحديدها أثناء التنفيذ.
-
الدالة ككائن من الدرجة الأولى: يمكن إسناد الدوال إلى متغيرات، وتمريرها كوسائط، وإرجاعها من دوال أخرى.
-
النماذج الأولية (Prototypes) مقابل الأصناف (Classes): تستخدم JavaScript نظامًا قائمًا على النماذج الأولية، رغم إدخال صيغة الأصناف في ES6.
-
الرفع (Hoisting): يتم “رفع” تصريحات المتغيرات والدوال إلى أعلى نطاقها.
-
الأحداث والدوال الراجعة (Callbacks): تعتمد JavaScript كثيرًا على الدوال الراجعة والوعود (Promises) لإدارة العمليات غير المتزامنة.
-
المساواة الضعيفة مقابل الصارمة: يجري
==تحويلًا للنوع، أما===فلا يفعل ذلك.
أفضل الممارسات
لكتابة JavaScript حديثة نظيفة وقابلة للصيانة:
-
استخدموا
constافتراضيًا، وletإذا احتجتم إلى إعادة الإسناد، وتجنبواvar. -
فضّلوا الدوال السهمية للدوال القصيرة والدوال الراجعة (callbacks).
-
استخدموا التفكيك (Destructuring) لاستخراج القيم من الكائنات أو المصفوفات.
-
طبّقوا القوالب النصية (template literals) للسلاسل متعددة الأسطر أو التي تتضمن استيفاء قيم.
-
تجنبوا المقارنات الضعيفة (
==،!=)، وفضّلوا المقارنات الصارمة (===،!==). -
استخدموا القيم الافتراضية للمعاملات وعوامل الانتشار (spread).
-
اعتمدوا دوال المصفوفات الحديثة مثل
mapوfilterوreduceبدلًا من الحلقات التقليدية عندما يكون ذلك مناسبًا. -
تعاملوا مع العمليات غير المتزامنة بشكل صحيح باستخدام Promises وasync/await (وهو ما سنتناوله في درس لاحق).
تمارين عملية
لترسيخ معارفكم، جرّبوا هذه التمارين:
-
اكتبوا دالة تأخذ مصفوفة من الأعداد وتُرجع مجموع الأعداد الزوجية.
-
أنشئوا كائنًا يمثل كتابًا بخصائص مثل العنوان والمؤلف، ودالة لعرض هذه المعلومات.
-
اكتبوا دالة تأخذ سلسلة نصية وتُرجع كائنًا يحتوي على عدد مرات ظهور كل حرف.
-
أنشئوا دالة تحوّل درجة الحرارة من Celsius إلى Fahrenheit أو العكس، وفقًا لمعامل يحدد الوضع.
-
استخدموا التفكيك (Destructuring) لتبديل قيمتَي متغيرين دون استخدام متغير مؤقت.
الخاتمة
في هذا الدرس، استكشفنا أساسيات JavaScript الحديثة:
- الطرق المختلفة للتصريح عن المتغيرات (
letوconstوvar) - أنواع البيانات (الأولية والمرجعية)
- العوامل (الحسابية، وعوامل المقارنة، والمنطقية)
- التفكيك وعوامل الانتشار
- هياكل التحكم (الشرطية والحلقات)
- المدخلات/المخرجات الأساسية
تشكّل هذه المفاهيم الأساس الذي ستبنون عليه فهمكم لـ JavaScript الحديثة. ومع تقدمكم، ستكتشفون كيف تتكامل هذه العناصر لإنشاء تطبيقات ويب ديناميكية وتفاعلية.
في الدرس القادم، سنستكشف الدوال الحديثة وميزاتها الجديدة.
هل تحتاجون إلى مراجعة الأساسيات؟ اطّلعوا على الدرس التمهيدي.
هل أنتم مستعدون للمتابعة؟ انتقلوا إلى الدرس التالي حول الدوال.
التعليقات
التعليقات مدعومة عبر GitHub Discussions
سجّل الدخول باستخدام GitHub للمشاركة في النقاش