0%
JavaScript الحديثة: Destructuring وSpread

Destructuring

التعامل الحديث مع البيانات

10-15 دقيقة

JavaScript الحديثة: Destructuring وSpread Operator

يُعدّ الـ destructuring (التفكيك) والـ spread operator (عامل الانتشار) ميزتين قويتين ظهرتا مع ES6، وهما تُبسّطان إلى حد كبير التعامل مع المصفوفات والكائنات في JavaScript.

الـ Destructuring

يتيح التفكيك استخراج القيم من الكائنات أو المصفوفات وإسنادها إلى متغيرات منفصلة بطريقة موجزة.

تفكيك الكائنات

// تفكيك كائن بسيط
const personne = {
    nom: "Dupont",
    prenom: "Marie",
    age: 30
};

const { nom, prenom, age } = personne;
console.log(nom);    // "Dupont"
console.log(prenom); // "Marie"
console.log(age);    // 30

// مع أسماء متغيرات مختلفة
const { nom: nomFamille, prenom: prenomPersonne } = personne;
console.log(nomFamille);     // "Dupont"
console.log(prenomPersonne); // "Marie"

// مع قيم افتراضية
const { pays = "France", ville = "Paris" } = personne;
console.log(pays);  // "France" (قيمة افتراضية)
console.log(ville); // "Paris" (قيمة افتراضية)

التفكيك المتداخل

const utilisateur = {
    id: 1,
    infos: {
        nom: "Dupont",
        adresse: {
            rue: "123 rue Principale",
            ville: "Paris"
        }
    }
};

// تفكيك متداخل
const { infos: { nom, adresse: { ville } } } = utilisateur;
console.log(nom);   // "Dupont"
console.log(ville); // "Paris"

تفكيك المصفوفات

// تفكيك مصفوفة أساسي
const couleurs = ["rouge", "vert", "bleu"];
const [premiere, deuxieme, troisieme] = couleurs;
console.log(premiere);  // "rouge"
console.log(deuxieme); // "vert"
console.log(troisieme); // "bleu"

// تجاهل بعض العناصر
const [,, derniere] = couleurs;
console.log(derniere); // "bleu"

// مع قيمة افتراضية
const [a, b, c, d = "jaune"] = couleurs;
console.log(d); // "jaune"

// نمط rest مع المصفوفات
const [premier, ...reste] = couleurs;
console.log(premier); // "rouge"
console.log(reste);   // ["vert", "bleu"]

التفكيك في معاملات الدوال

// التفكيك في المعاملات
function afficherUtilisateur({ nom, age, email = "non fourni" }) {
    console.log(`Nom: ${nom}, Age: ${age}, Email: ${email}`);
}

afficherUtilisateur({
    nom: "Dupont",
    age: 30
}); // "Nom: Dupont, Age: 30, Email: non fourni"

// مع مصفوفة
function afficherCoordonnees([x, y, z = 0]) {
    console.log(`X: ${x}, Y: ${y}, Z: ${z}`);
}

afficherCoordonnees([10, 20]); // "X: 10, Y: 20, Z: 0"

الـ Spread Operator

يتيح عامل الانتشار (...) تفكيك كائن قابل للتكرار (مثل المصفوفة أو السلسلة النصية) إلى عناصره الفردية.

مع المصفوفات

// نسخ مصفوفة
const original = [1, 2, 3];
const copie = [...original];
console.log(copie); // [1, 2, 3]

// دمج المصفوفات
const tableau1 = [1, 2];
const tableau2 = [3, 4];
const combine = [...tableau1, ...tableau2];
console.log(combine); // [1, 2, 3, 4]

// إضافة عناصر
const nombres = [1, 2, 3];
const plusNombres = [...nombres, 4, 5];
console.log(plusNombres); // [1, 2, 3, 4, 5]

// في استدعاءات الدوال
function somme(x, y, z) {
    return x + y + z;
}

const nombres2 = [1, 2, 3];
console.log(somme(...nombres2)); // 6

مع الكائنات (Object Spread)

// نسخ كائن
const original = { a: 1, b: 2 };
const copie = { ...original };
console.log(copie); // { a: 1, b: 2 }

// دمج الكائنات
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const cloned = { ...obj1 }; // { foo: "bar", x: 42 }
const merged = { ...obj1, ...obj2 }; // { foo: "baz", x: 42, y: 13 }

// إضافة الخصائص/استبدالها
const base = { a: 1, b: 2 };
const nouveau = { ...base, b: 3, c: 4 };
console.log(nouveau); // { a: 1, b: 3, c: 4 }

حالات استخدام متقدمة

// مع السلاسل النصية
const str = "Hello";
const chars = [...str];
console.log(chars); // ["H", "e", "l", "l", "o"]

// في بناء المصفوفات
const parts = ["épaules", "genoux"];
const corps = ["tête", ...parts, "orteils"];
console.log(corps); // ["tête", "épaules", "genoux", "orteils"]

// مع Set
const monSet = new Set([1, 2, 3]);
const tableau = [...monSet];
console.log(tableau); // [1, 2, 3]

// الجمع بين التفكيك والانتشار
const { a, b, ...reste } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a);     // 1
console.log(b);     // 2
console.log(reste); // { c: 3, d: 4 }

الأنماط وأفضل الممارسات

نمط إعادة التسمية مع التفكيك

// إعادة التسمية أثناء التفكيك
const api = {
    user_id: 123,
    user_name: "john_doe",
    user_email: "john@example.com"
};

const {
    user_id: id,
    user_name: username,
    user_email: email
} = api;

console.log(id);       // 123
console.log(username); // "john_doe"

المعاملات الافتراضية مع التفكيك

function configurer({
    couleur = "bleu",
    taille = "medium",
    type = "normal"
} = {}) {
    console.log(`Couleur: ${couleur}, Taille: ${taille}, Type: ${type}`);
}

configurer(); // يستخدم جميع القيم الافتراضية
configurer({ couleur: "rouge" }); // يستبدل اللون فقط

النسخ العميق مقابل النسخ السطحي

// انتبه: spread ينشئ نسخة سطحية
const original = { 
    a: 1, 
    b: { 
        c: 2 
    } 
};

const copieSuperf = { ...original };
copieSuperf.b.c = 3;
console.log(original.b.c); // 3 (الكائن المتداخل مشترك)

// للحصول على نسخة عميقة، استخدم:
const copieProf = JSON.parse(JSON.stringify(original));
// أو استخدم مكتبات مثل lodash.cloneDeep

الجمع مع ميزات ES6+ الأخرى

// مع template literals
const personne = {
    nom: "Alice",
    competences: ["JS", "React", "Node"]
};

const { nom, competences: [principale, ...autres] } = personne;
console.log(`${nom} maîtrise principalement ${principale}`);
// "Alice maîtrise principalement JS"

// مع الدوال السهمية
const creerUtilisateur = ({ nom, age }) => ({
    nom,
    age,
    dateCreation: new Date()
});

const utilisateur = creerUtilisateur({ nom: "Bob", age: 25 });

حالات استخدام عملية

في React

// تفكيك الـ props
function UserProfile({ name, age, email }) {
    return (
        <div>
            <h2>{name}</h2>
            <p>Age: {age}</p>
            <p>Email: {email}</p>
        </div>
    );
}

// spread مع الـ props
const buttonProps = {
    type: "submit",
    className: "btn-primary",
    onClick: () => console.log("Cliqué!")
};

<button {...buttonProps}>Envoyer</button>

في واجهات REST API

// استخراج البيانات من استجابة API
async function getUser(id) {
    const response = await fetch(`/api/users/${id}`);
    const { name, email, ...metadata } = await response.json();
    
    return {
        displayName: name,
        contact: email,
        metadata
    };
}

// بناء الطلب
const defaultParams = {
    method: "GET",
    headers: {
        "Content-Type": "application/json"
    }
};

const fetchData = (url, options) => 
    fetch(url, { ...defaultParams, ...options });

تمارين عملية

  1. استخراج البيانات
// تمرين: استخراج المعلومات المناسبة
const donnees = {
    utilisateur: {
        nom: "Dupont",
        adresse: {
            rue: "123 rue Principale",
            ville: "Paris",
            pays: "France"
        },
        preferences: {
            theme: "sombre",
            notifications: true
        }
    }
};

// الحل
const { 
    utilisateur: { 
        nom,
        adresse: { ville },
        preferences: { theme }
    }
} = donnees;

console.log(`${nom} vit à ${ville} et préfère le thème ${theme}`);
  1. دمج الكائنات
// تمرين: دمج الإعدادات
const configDefaut = {
    theme: "clair",
    langue: "fr",
    notifications: true
};

const configUtilisateur = {
    theme: "sombre",
    notifications: false
};

// الحل
const configFinale = { ...configDefaut, ...configUtilisateur };
console.log(configFinale);
// { theme: "sombre", langue: "fr", notifications: false }
  1. التعامل مع المصفوفات
// تمرين: إعادة ترتيب مصفوفة
const nombres = [1, 2, 3, 4, 5];

// الحل
const [premier, deuxieme, ...autres] = nombres;
const reorganise = [...autres, deuxieme, premier];
console.log(reorganise); // [3, 4, 5, 2, 1]

الخلاصة

يُعدّ الـ destructuring والـ spread operator أداتين أساسيتين في JavaScript الحديثة، وهما تتيحان:

  • استخراج البيانات بسهولة من البنى المعقدة
  • إنشاء نسخ من الكائنات والمصفوفات
  • دمج البيانات بطريقة أنيقة
  • جعل الشيفرة أكثر وضوحًا وقابلية للصيانة

وتفيد هذه الميزات بشكل خاص في:

  • التعامل مع بيانات واجهات API
  • التطوير باستخدام React/Vue.js
  • إدارة حالة التطبيق
  • معالجة الإعدادات

في الدرس القادم، سنستكشف البرمجة كائنية التوجه في JavaScript الحديثة.


هل تحتاج إلى مراجعة الدوال؟ راجع الدرس السابق عن الدوال.

هل أنت مستعد للمتابعة؟ انتقل إلى الدرس التالي عن البرمجة كائنية التوجه.

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!