JavaScript / أساسي: القيم وأسس المتصفح / الدرس 5
الكائنات والمصفوفات والتحديث المقصود
مثّل سجلات الدورات وحوّل المجموعات دون تعديل مشترك عرضي. تعلّم قراءة الخصائص والغياب ودوال المصفوفات وحدود النسخ.
في هذه الصفحة
أهداف الدرس
- اختيار السجلات والمجموعات لأغراض مختلفة.
- تحويل المصفوفات بنتائج راجعة صريحة.
- شرح الهوية والنسخ السطحي.
تمثل الخصائص حقائق مسماة
يجمع سجل الكائن حقائق مسماة مثل المعرف والعنوان والمقاعد. تستخدم النقطة اسم خاصية حرفياً، وتقيّم الأقواس تعبير المفتاح فتفيد للاختيار الديناميكي. ميّز الغائب من خاصية ذاتية قيمتها undefined باستخدام Object.hasOwn إن اهتم العقد بذلك. لا تستنتج الوجود من الصدق لأن الصفر قد يكون صالحاً. وقد تعبّر Map عن قاموس مفاتيح اعتباطية دون وراثة نموذج أولي غير مقصودة. صغّر الشكل العام وتحقق من السجلات الواردة قبل الوثوق بقيمها.
استخدام filter وmap وreduce بغرض واضح
تصف دوال المصفوفة تحويلات مختلفة: تختار filter وفق قرار منطقي، وتعيد map مقابلاً لكل عنصر تزوره، وتجمع reduce التسلسل في مراكِم. سمّ النتيجة الوسيطة إذا أخفت السلسلة الطويلة القاعدة التجارية. يختار المثال المتاح قبل استخراج العناوين فلا يصل المغلق للنتيجة. لا تنسخ هذه الدوال كائنات العناصر تلقائياً؛ فقد تحوي المصفوفة المصفاة مراجع للسجلات الأصلية، وهو مهم إذا عدلت الخطوة التالية عنصراً بدلاً من إنتاج قيمة جديدة.
const courses = [
{ title: "DOM", seats: 2 },
{ title: "Async", seats: 0 }
];
const titles = courses.filter(c => c.seats > 0).map(c => c.title);
const seats = courses.reduce((sum, c) => sum + c.seats, 0);
console.log(JSON.stringify(titles), seats);
["DOM"] 2
تحوي قائمة العناوين DOM فقط. وتجعل البداية الصفرية مجموع المصفوفة الفارغة محدداً.
قد يعدّل الترتيب المصدر ويقارن على نحو مفاجئ
تتعامل مقارنة sort الافتراضية مع القيم كنصوص، فتحتاج المبالغ العددية مقارناً عددياً. وتعدل sort المصفوفة المستقبلة؛ انسخ أولاً إن كان ترتيب الأصل مهماً أو استخدم بديلاً ناسخاً مدعوماً مثل toSorted. يجب أن يصف المقارن الترتيب باتساق ويعيد سالباً أو صفراً أو موجباً. تجنب إرجاع منطقي فقط لأنه يبهم التساوي والترتيب. راعِ المقارنة المحلية للغة البشرية، واختبر القيم المرتبة وحفظ الأصل إذا نص العقد عليه.
نسخ المسار المراد تغييره
ينشئ النشر مصفوفة أو كائناً جديداً في مستوى واحد، وتبقى السجلات المتداخلة مشتركة إن لم تنسخ. لتحديث إعداد انسخ السجل الخارجي وسجل التفضيل الذي تغيره، وأعد استخدام غير المرتبط الثابت عمداً. ليس تسلسل JSON ناسخاً عاماً؛ إذ يغير قيماً أو يرفضها ويفقد السلوك وعلاقات الهوية. يدعم structuredClone بنى كثيرة لكنه إمكان بيئة له قيود. اختر النسخ من عقد البيانات الفعلي لا من سطر مريح تسميه نسخاً عميقاً.
const original = { name: "A", preferences: { theme: "light" } };
const draft = { ...original, preferences: { ...original.preferences } };
draft.preferences.theme = "dark";
const amounts = [100, 20, 3];
const ordered = [...amounts].sort((a, b) => a - b);
console.log(original.preferences.theme, draft.preferences.theme);
console.log(ordered.join(","), amounts.join(","));
light dark
3,20,100 100,20,3
ينسخ المسار المتداخل المعدل فقط. ويحفظ نسخ مصفوفة المبالغ ترتيب الأصل من sort.
تختلف المجموعة الفارغة عن السجل الغائب
تعيد find أول مطابق أو undefined، وتعطي filter مصفوفة دائماً. لذلك قد ترمي قراءة find(...).title دون فحص. المصفوفة الفارغة صادقة منطقياً؛ افحص length لوجود المطابقات. تجنب الفراغات المتناثرة بدلاً من سجلات غياب صريحة لأن المرور قد يعاملها بطرق مختلفة. يوحّد الحد الجيد قائمة صالحة ويجعل الغياب نتيجة مقصودة. ثبّت المعرفات كي لا يغير الترشيح أو الترتيب السجل المقصود بالفعل.
الأخطاء الشائعة وإصلاحها
ترتيب الأعداد كنصوص
- لماذا يحدث؟
- استدعاء sort دون مقارن مناسب.
- كيف تصلحه؟
- استخدام مقارن عددي وتحديد التعديل أو النسخ عمداً.
- كيف تتجنب تكراره؟
- اختبار قيم بأطوال أرقام مختلفة.
تعديل المسودة لتفضيلات الأصل
- لماذا يحدث؟
- نسخ الكائن الخارجي فقط.
- كيف تصلحه؟
- نسخ المسار المتداخل المعدل.
- كيف تتجنب تكراره؟
- فحص الهوية والقيم بالعمق المهم.
تسبب نتيجة بحث غائبة TypeError
- لماذا يحدث؟
- افتراض إرجاع find سجلاً دائماً.
- كيف تصلحه؟
- معالجة undefined قبل قراءة الحقول.
- كيف تتجنب تكراره؟
- اختبار غياب المطابقة والمدخل الفارغ.
اختبر فهمك
1. احسب إجمالي [125, 250, 0] بالسنتات دون تعديلها.
اعرض الحل المشروح
استخدم reduce((sum, cents) => sum + cents, 0) فتنتج 375، وتعالج البداية المصفوفة الفارغة بصفر. تحقق من المبالغ أولاً؛ فقد يحول النص الجمع إلى وصل ويخالف السالب المجال.
2. لماذا لا يعزل {...user} الحقل user.address.city؟
اعرض الحل المشروح
ينسخ النشر مرجع address لا الكائن المتداخل. أنشئ {...user, address: {...user.address, city: "New"}} للشكل المعروف. يصبح الخارج والعنوان جديدين، وتبقى بقية الحقول وفق سياسة المشاركة الموثقة.
أهم ما تعلمته
- لدوال التحويل عقود إرجاع وتعديل مختلفة.
- لا يعزل نسخ مستوى واحد جميع القيم المتداخلة.