المراجعة الشاملة لـ JavaScript

كل مفاهيم الكورس في مكان واحد — من المتغيرات إلى قواعد البيانات. راجع كل شيء قبل الاختبار النهائي.

1

المتغيرات وأنواع البيانات

الإعلان عن المتغيرات: let / const / var

const

للقيم الثابتة التي لا تتغير. يجب تعيين القيمة فور الإعلان.

let

للقيم التي قد تتغير لاحقاً. نطاقها داخل الـ block فقط.

var

قديم ولا يُنصح به. نطاقه الدالة بأكملها — يسبب أخطاء خفية.

// ✅ الطريقة الحديثة const gameName = "Valorant"; // لا تتغير أبداً let playerScore = 0; // ستتغير أثناء اللعب let isLoggedIn = false; // قيمة منطقية // ❌ محاولة تغيير const تسبب خطأ // gameName = "CS2"; → TypeError! // إعادة الإعلان بـ let لاحقاً playerScore = 500; isLoggedIn = true;

أنواع البيانات السبعة (Data Types)

النوعمثالالوصفtypeof
String "Ahmed" نصوص — داخل "" أو '' أو `` "string"
Number 42, 3.14, -7 أرقام صحيحة أو عشرية "number"
Boolean true / false صح أو خطأ فقط "boolean"
Null null قيمة فارغة متعمدة "object"*
Undefined undefined متغير معلن ولم يُعطَ قيمة "undefined"
Object { name: "Ali" } مجموعة خصائص "object"
Array [1, 2, 3] قائمة مرتبة (نوعها object) "object"
* خطأ مشهور في JS: typeof null === "object" رغم أن null ليست object. هذا bug قديم لن يُصلَح.

دمج النصوص (String Interpolation)

const name = "Ahmed"; const level = 42; // الطريقة القديمة (Concatenation) console.log("مرحباً يا " + name + "، مستواك: " + level); // الطريقة الحديثة — Template Literals (Backticks) console.log(`مرحباً يا ${name}، مستواك: ${level}`); console.log(`ضعف المستوى: ${level * 2}`); // يمكن كتابة تعابير داخل ${} // Template Literals تدعم الأسطر المتعددة const msg = ` اللاعب: ${name} المستوى: ${level} الحالة: نشط `;

تحويل أنواع البيانات (Type Conversion)

// String → Number const strNum = "42"; Number(strNum) // → 42 parseInt("42.9px") // → 42 (يأخذ الجزء الصحيح) parseFloat("3.14") // → 3.14 +"100" // → 100 (اختصار) // Number → String (42).toString() // → "42" String(42) // → "42" // أي قيمة → Boolean Boolean(0) // → false (Falsy) Boolean("") // → false (Falsy) Boolean("hello") // → true (Truthy) Boolean([]) // → true (Truthy — مصفوفة فارغة!)
2

الشروط والحلقات التكرارية

الشرط if / else if / else

let score = 78; if (score >= 90) { console.log("A — ممتاز"); } else if (score >= 75) { console.log("B — جيد جداً"); } else if (score >= 60) { console.log("C — مقبول"); } else { console.log("F — راسب"); } // النتيجة: "B — جيد جداً"

Switch وTernary

// Switch — للمقارنة بقيم محددة switch (day) { case "Mon": console.log("أول أسبوع"); break; case "Fri": console.log("آخر دوام"); break; default: console.log("يوم عادي"); } // Ternary — if/else في سطر واحد const status = age >= 18 ? "بالغ" : "قاصر"; // Logical Short-circuit const name = user?.name || "ضيف"; // لو لا يوجد اسم

أنواع الحلقات التكرارية

for — الأكثر شيوعاً

for (let i = 0; i < 5; i++) { console.log(`الجولة: ${i}`); } // for...of — للمرور على مصفوفة const games = ["GTA", "FIFA", "MC"]; for (const game of games) { console.log(game); // GTA, FIFA, MC }

while — عندما لا نعرف عدد التكرارات

let hp = 100; while (hp > 0) { hp -= Math.random() * 25; console.log(`HP: ${Math.floor(hp)}`); } console.log("Game Over"); // for...in — للمرور على Object const user = {name:"Ali", age:20}; for (const key in user) { console.log(`${key}: ${user[key]}`); }
break و continue: break يوقف الحلقة كلياً. continue يتخطى الدورة الحالية ويكمل للتالية.
3

الدوال — المصنع الذكي للكود

أنواع الدوال الثلاثة

// 1. Function Declaration — يمكن استدعاؤها قبل تعريفها (Hoisting) function greet(name = "ضيف") { // Default Parameter return `أهلاً يا ${name}!`; } greet("Ahmed"); // → "أهلاً يا Ahmed!" greet(); // → "أهلاً يا ضيف!" // 2. Function Expression — مخزنة في متغير const square = function(n) { return n * n; }; // 3. Arrow Function — الأكثر استخداماً في الكود الحديث const multiply = (a, b) => a * b; // سطر واحد const add = (a, b) => { return a + b; }; // أو مع block // دالة تقبل دالة أخرى (Higher-Order Function) function applyTwice(fn, value) { return fn(fn(value)); } applyTwice(n => n * 2, 3); // → 12 (3→6→12)

Scope والـ Closure

// Global vs Local Scope const globalVar = "مرئي للكل"; function myFunc() { const localVar = "داخل الدالة فقط"; console.log(globalVar); // ✅ } // console.log(localVar); // ❌ ReferenceError // Closure — الدالة تتذكر بيئتها function makeCounter() { let count = 0; return () => ++count; } const counter = makeCounter(); counter(); // 1 counter(); // 2 — يتذكر count!

Callbacks وArray Methods

const nums = [10, 25, 6, 40, 13]; // map — يحول كل عنصر ويعيد مصفوفة جديدة nums.map(n => n * 2); // [20,50,12,80,26] // filter — يرجع العناصر المطابقة للشرط nums.filter(n => n > 15); // [25, 40] // find — أول عنصر مطابق nums.find(n => n > 20); // 25 // reduce — يجمع كل شيء في قيمة واحدة nums.reduce((acc, n) => acc + n, 0); // 94 // every / some nums.every(n => n > 0); // true nums.some(n > 30); // true
4

المصفوفات والكائنات

عمليات المصفوفات الأساسية

const games = ["Roblox", "Minecraft", "Fortnite"]; // الوصول — الفهرس يبدأ من 0 games[0] // "Roblox" games[games.length-1] // "Fortnite" (آخر عنصر) games.at(-1) // "Fortnite" (الطريقة الحديثة) // إضافة وحذف games.push("Valorant") // أضف للآخر games.unshift("GTA") // أضف للأول games.pop() // احذف الأخير games.shift() // احذف الأول games.splice(1, 1) // احذف من index 1 عنصراً واحداً // البحث games.indexOf("Minecraft") // 1 games.includes("FIFA") // false // نسخ ودمج const copy = [...games]; // Spread للنسخ const all = ["CS2", ...games, "FIFA"]; // دمج const sliced = games.slice(0, 2); // أول عنصرين

الكائنات (Objects) والتفكيك (Destructuring)

const player = { name: "Ahmed", level: 42, skills: ["Sniper", "Driver"], stats: { kills: 1200, deaths: 300 }, getKD() { return (this.stats.kills / this.stats.deaths).toFixed(2); } }; // الوصول player.name // "Ahmed" player["level"] // 42 (مفيد للمفاتيح المتغيرة) player.getKD() // "4.00" // Destructuring — استخراج القيم بذكاء const { name, level, stats: { kills } } = player; console.log(name, level, kills); // Ahmed 42 1200 // إضافة وتعديل وحذف خصائص player.rank = "Gold"; // إضافة player.level = 50; // تعديل delete player.rank; // حذف // Object Methods Object.keys(player) // ["name", "level", ...] Object.values(player) // ["Ahmed", 42, ...] Object.entries(player) // [["name","Ahmed"], ...] // نسخ Object (Spread) const updated = { ...player, level: 55 }; // نسخة جديدة مع تغيير
5

التحكم في الـ DOM

اختيار العناصر وتعديلها

// ─── اختيار العناصر ─── const el = document.getElementById("myId"); const el2 = document.querySelector(".myClass"); // أول مطابق const all = document.querySelectorAll("p"); // NodeList // ─── تعديل المحتوى ─── el.innerText = "نص جديد"; // نص فقط el.innerHTML = "<b>نص غامق</b>"; // يدعم HTML el.textContent = "نص بدون تنسيق"; // أسرع وأأمن // ─── تعديل الـ CSS ─── el.style.backgroundColor = "#ff0"; el.style.display = "none"; // ─── الـ classList ─── el.classList.add("active"); el.classList.remove("hidden"); el.classList.toggle("dark-mode"); el.classList.contains("active"); // true/false // ─── الـ Attributes ─── el.setAttribute("href", "#"); el.getAttribute("id"); el.dataset.userId; // يقرأ data-user-id // ─── إنشاء وحذف عناصر ─── const div = document.createElement("div"); div.innerHTML = "<p>محتوى جديد</p>"; document.body.appendChild(div); // إضافة div.remove(); // حذف
6

الأحداث (Events)

addEventListener وأهم الأحداث

const btn = document.querySelector("#myBtn"); // الطريقة الصحيحة للاستماع للأحداث btn.addEventListener("click", (event) => { event.preventDefault(); // منع السلوك الافتراضي (مثل submit) console.log("تم الضغط!", event.target); }); // أهم الأحداث: // click / dblclick — النقر // mouseover / mouseout — تمرير الفأرة // keydown / keyup — لوحة المفاتيح // input / change — تغيير حقل النص // submit — إرسال نموذج // load / DOMContentLoaded — تحميل الصفحة // scroll — التمرير // Event Delegation — استمع على الأب بدلاً من كل ابن document.querySelector("#gameList").addEventListener("click", (e) => { if (e.target.tagName === "LI") { console.log("ضغطت على:", e.target.textContent); } });
7

البرمجة غير المتزامنة وربط الـ APIs

Promises وAsync/Await — الفهم الحقيقي

طلب fetch()
Promise (Pending)
await
Fulfilled / Rejected
try / catch
// ─── Promise الأساسية ─── const myPromise = new Promise((resolve, reject) => { const success = true; if (success) resolve({ data: "نجح الطلب" }); else reject("حدث خطأ"); }); // ─── Async/Await — الطريقة المحترفة ─── async function fetchPlayerData(playerId) { try { // 1. إرسال الطلب const res = await fetch(`https://api.game.com/players/${playerId}`); // 2. التحقق من نجاح الاستجابة if (!res.ok) throw new Error(`HTTP Error: ${res.status}`); // 3. تحويل الرد إلى JSON const player = await res.json(); // 4. استخدام البيانات console.log(`اللاعب: ${player.name}، الرتبة: ${player.rank}`); return player; } catch (error) { console.error("فشل جلب البيانات:", error.message); return null; } } // ─── POST Request — إرسال بيانات للسيرفر ─── async function saveScore(score) { const res = await fetch("https://api.game.com/scores", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ score, timestamp: Date.now() }) }); return res.json(); } // ─── Promise.all — تنفيذ طلبات متعددة بالتوازي ─── const [players, maps, rankings] = await Promise.all([ fetch("/api/players").then(r => r.json()), fetch("/api/maps").then(r => r.json()), fetch("/api/rankings").then(r => r.json()) ]); // كلها تُنفَّذ معاً — أسرع بكثير
8

ميزات ES6+ الأساسية

Destructuring متقدم

// Array Destructuring const [first, second, ...rest] = [1,2,3,4]; // first=1, second=2, rest=[3,4] // Object Destructuring مع إعادة التسمية const { name: playerName, level = 1 } = user; // playerName = user.name, level أو 1 كافتراضي // Swap بدون متغير مؤقت let a = 1, b = 2; [a, b] = [b, a]; // a=2, b=1

Optional Chaining وNullish

const user = { profile: { avatar: "pic.jpg" } }; // ?. — لا يرمي خطأ إذا القيمة null/undefined user?.profile?.avatar // "pic.jpg" user?.settings?.theme // undefined (لا خطأ) // ?? — القيمة الافتراضية إذا null/undefined فقط const theme = user?.settings?.theme ?? "dark"; // إذا لم يوجد theme → "dark" // ||= و &&= و ??= user.score ||= 0; // إذا falsy → 0 user.name ??= "ضيف"; // إذا null/undefined → ضيف

Modules (Import / Export)

// ─── math.js ─── export const add = (a, b) => a + b; export const PI = 3.14159; export default function calculate() { /* ... */ } // ─── main.js ─── import calculate, { add, PI } from "./math.js"; import * as MathUtils from "./math.js"; // استيراد الكل
9

البرمجة كائنية التوجه (OOP)

Classes والوراثة (Inheritance)

// ─── الـ Class الأساسية ─── class Character { // Private Fields (خاصة لا تُرى من الخارج) #health; constructor(name, hp) { this.name = name; this.#health = hp; } // Getter — للوصول للقيم الخاصة get hp() { return this.#health; } attack(target, damage) { console.log(`${this.name} attacks ${target.name} for ${damage}!`); target.takeDamage(damage); } takeDamage(dmg) { this.#health = Math.max(0, this.#health - dmg); } // Static — يُستدعى على الـ Class مباشرة static create(name) { return new Character(name, 100); } toString() { return `${this.name} (HP: ${this.hp})`; } } // ─── الوراثة (Inheritance) ─── class Warrior extends Character { constructor(name) { super(name, 150); // استدعاء Constructor الأب this.armor = 30; } // تجاوز (Override) دالة الأب takeDamage(dmg) { const reduced = Math.max(0, dmg - this.armor); super.takeDamage(reduced); // استدعاء دالة الأب } } const hero = new Warrior("Ahmed"); const boss = Character.create("Dragon"); boss.attack(hero, 50); // Warrior يمتص 30 درع → يأخذ 20 ضرر فقط
10

ربط قواعد البيانات

Firebase Firestore

import { getFirestore, collection, addDoc, getDocs, onSnapshot } from "firebase/firestore"; const db = getFirestore(app); const ref = collection(db, "scores"); // كتابة await addDoc(ref, { name:"Ahmed", score:999 }); // قراءة مرة واحدة const snap = await getDocs(ref); snap.forEach(d => console.log(d.data())); // استماع مباشر Real-time onSnapshot(ref, snap => { snap.forEach(d => renderScore(d.data())); });

Supabase

import { createClient } from "@supabase/supabase-js"; const sb = createClient(URL, ANON_KEY); // SELECT const { data } = await sb .from("scores") .select("*") .order("score", { ascending: false }) .limit(10); // INSERT await sb.from("scores") .insert({ name:"Ahmed", score:500 }); // Real-time sb.channel("scores") .on("postgres_changes", { event:"INSERT", schema:"public", table:"scores" }, payload => { renderScore(payload.new); }).subscribe();
الفرق الجوهري: Firebase → NoSQL مرنة، مثالية للبدء السريع. Supabase → PostgreSQL منظمة، مثالية للعلاقات المعقدة والاستعلامات القوية.