JavaScript المتقدم (ES6+)

صيغ الكائنات المحسّنة

13 دقيقة الدرس 7 من 40

صيغ الكائنات المحسّنة

قدم ES6 العديد من التحسينات على صيغة الكائنات الحرفية التي تجعل إنشاء الكائنات والعمل معها أكثر إيجازاً وقوة. تقلل هذه الميزات من التعليمات البرمجية النمطية وتجعل JavaScript أكثر قابلية للقراءة والصيانة.

اختصار الخاصية

عندما يتطابق اسم الخاصية مع اسم المتغير، يمكنك استخدام صيغة مختصرة لتجنب التكرار:

// ES5 - صيغة مطولة const name = 'Alice'; const age = 30; const city = 'New York'; const person = { name: name, age: age, city: city }; // ES6+ - اختصار الخاصية const personES6 = { name, age, city }; console.log(personES6); // { name: 'Alice', age: 30, city: 'New York' }
نصيحة: اختصار الخاصية مفيد بشكل خاص عند إنشاء كائنات من معاملات الدالة أو القيم المفككة، مما يجعل كودك أكثر نظافة.

اختصار الدالة

يمكنك تعريف الدوال بشكل أكثر إيجازاً بدون كلمة function:

// ES5 - صيغة الدالة التقليدية const calculator = { add: function(a, b) { return a + b; }, subtract: function(a, b) { return a - b; } }; // ES6+ - اختصار الدالة const calculatorES6 = { add(a, b) { return a + b; }, subtract(a, b) { return a - b; }, multiply(a, b) { return a * b; } }; console.log(calculatorES6.add(5, 3)); // 8 console.log(calculatorES6.multiply(4, 2)); // 8

أسماء الخصائص المحسوبة

يمكنك استخدام التعبيرات كأسماء خصائص عن طريق لفها بأقواس مربعة:

// أسماء خصائص ديناميكية const propName = 'score'; const student = { name: 'Bob', [propName]: 95, ['grade' + 'Level']: 'A' }; console.log(student); // { name: 'Bob', score: 95, gradeLevel: 'A' } // استخدام الأسماء المحسوبة مع الدوال const createUser = (field, value) => ({ id: Date.now(), [field]: value }); console.log(createUser('username', 'alice123')); // { id: 1707123456789, username: 'alice123' } console.log(createUser('email', 'alice@example.com')); // { id: 1707123456790, email: 'alice@example.com' }
ملاحظة: يتم تقييم أسماء الخصائص المحسوبة عند إنشاء الكائن، مما يسمح لك ببناء هياكل كائنات ديناميكية بناءً على قيم وقت التشغيل.

دمج الصيغ المختصرة

يمكنك مزج ومطابقة جميع هذه الميزات لإنشاء كائنات نظيفة وموجزة:

const firstName = 'John'; const lastName = 'Doe'; const age = 28; const user = { // اختصار الخاصية firstName, lastName, age, // خاصية محسوبة ['full' + 'Name']() { return `${this.firstName} ${this.lastName}`; }, // اختصار الدالة greet() { return `Hello, I'm ${this.fullName()}`; }, // خاصية عادية role: 'developer' }; console.log(user.fullName()); // "John Doe" console.log(user.greet()); // "Hello, I'm John Doe"

مثال عملي: تنسيق استجابة API

function formatUser(id, username, email, isActive) { return { // اختصار الخاصية id, username, email, // خاصية محسوبة ['is' + 'Active']: isActive, // اختصار الدالة getStatus() { return this.isActive ? 'Active' : 'Inactive'; }, getProfile() { return `${this.username} (${this.email})`; }, // صيغة مختلطة metadata: { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() } }; } const user = formatUser(1, 'alice', 'alice@example.com', true); console.log(user.getProfile()); // "alice (alice@example.com)" console.log(user.getStatus()); // "Active"

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

تعمل صيغ الكائنات المحسّنة بشكل رائع مع التفكيك:

// استخراج وتحويل البيانات function processOrder({ id, product, quantity, price }) { const total = quantity * price; return { // اختصار الخاصية من المعاملات id, product, quantity, price, // قيمة محسوبة total, // دوال getDiscount(percentage) { return this.total * (percentage / 100); }, getFinalPrice(discountPercentage = 0) { return this.total - this.getDiscount(discountPercentage); } }; } const order = processOrder({ id: 101, product: 'Laptop', quantity: 2, price: 1000 }); console.log(order.total); // 2000 console.log(order.getFinalPrice(10)); // 1800 (خصم 10%)

أنماط إنشاء الكائنات الديناميكية

// إنشاء كائنات من المصفوفات const fields = ['name', 'email', 'age']; const values = ['Alice', 'alice@example.com', 30]; const userFromArrays = fields.reduce((obj, field, index) => ({ ...obj, [field]: values[index] }), {}); console.log(userFromArrays); // { name: 'Alice', email: 'alice@example.com', age: 30 } // بناء كائنات التكوين const createConfig = (env) => ({ environment: env, [`${env}Url`]: `https://${env}.example.com`, [`is${env.charAt(0).toUpperCase() + env.slice(1)}`]: true }); console.log(createConfig('production')); // { // environment: 'production', // productionUrl: 'https://production.example.com', // isProduction: true // }

تحسينات خصائص الكائن في الممارسة

// نمط إدارة الحالة const createStore = (initialState) => { let state = initialState; return { // Getter getState() { return { ...state }; }, // خاصية محسوبة مع timestamp ['last' + 'Updated']: Date.now(), // دالة التحديث setState(updates) { state = { ...state, ...updates }; this.lastUpdated = Date.now(); }, // دالة إعادة التعيين reset() { state = initialState; this.lastUpdated = Date.now(); } }; }; const store = createStore({ count: 0, user: null }); store.setState({ count: 5 }); console.log(store.getState()); // { count: 5, user: null }
أفضل الممارسات: استخدم اختصارات الخاصية والدالة كلما أمكن ذلك. إنها تقلل من الإسهاب في الكود وتجعل الكائنات أسهل في الصيانة. ومع ذلك، تذكر أن الدوال السهمية في اختصار الدالة يمكن أن تسبب مشاكل مع ربط this.

الأخطاء الشائعة

// ❌ الدوال السهمية تفقد سياق 'this' في الكائنات const badExample = { name: 'Alice', greet: () => { console.log(`Hello, ${this.name}`); // 'this' غير معرف! } }; // ✅ استخدم اختصار الدالة بدلاً من ذلك const goodExample = { name: 'Alice', greet() { console.log(`Hello, ${this.name}`); // يعمل بشكل صحيح } }; // ❌ خاصية محسوبة بدون أقواس const prop = 'score'; const wrong = { prop: 100 // ينشئ خاصية تسمى 'prop'، وليس 'score' }; // ✅ استخدم الأقواس للخصائص المحسوبة const correct = { [prop]: 100 // ينشئ خاصية تسمى 'score' };
مهم: اختصار الدالة ينشئ دوال عادية، وليست دوال سهمية. إذا كنت بحاجة إلى أن يشير this إلى الكائن، استخدم دائماً اختصار الدالة، وليس خصائص الدالة السهمية.

حالات الاستخدام في العالم الحقيقي

// 1. بناء كائنات طلب API const createRequest = (endpoint, method = 'GET', data = null) => ({ url: `https://api.example.com/${endpoint}`, method, ...(data && { body: JSON.stringify(data) }), headers: { 'Content-Type': 'application/json' }, send() { return fetch(this.url, { method: this.method, body: this.body, headers: this.headers }); } }); // 2. تحويل بيانات النموذج const processFormData = (form) => { const { username, email, password } = form; return { username, email, passwordHash: hashPassword(password), isValid() { return this.username && this.email && this.passwordHash; } }; }; // 3. تكوين الإضافة const createPlugin = (name, options = {}) => ({ name, enabled: true, ...options, init() { console.log(`Initializing plugin: ${this.name}`); }, ['destroy' + 'Plugin']() { console.log(`Destroying plugin: ${this.name}`); this.enabled = false; } });

تمرين تطبيقي:

المهمة: أنشئ كائن منتج باستخدام صيغ الكائنات المحسّنة:

  1. استخدم اختصار الخاصية لمتغيرات name و price و stock
  2. أضف خاصية محسوبة للفئة (باستخدام متغير)
  3. قم بتضمين دوال: getPrice() مع حساب الضريبة و isAvailable()

الحل:

const name = 'Laptop'; const price = 999; const stock = 15; const categoryType = 'category'; const taxRate = 0.1; const product = { // اختصار الخاصية name, price, stock, // خاصية محسوبة [categoryType]: 'Electronics', // دوال getPrice(includeTax = true) { return includeTax ? this.price * (1 + taxRate) : this.price; }, isAvailable() { return this.stock > 0; }, getInfo() { return `${this.name} - $${this.getPrice()} (${this.stock} in stock)`; } }; console.log(product.getInfo()); // "Laptop - $1098.9 (15 in stock)" console.log(product.isAvailable()); // true

الملخص

في هذا الدرس، تعلمت:

  • اختصار الخاصية يلغي التكرار عندما تتطابق أسماء الخصائص مع المتغيرات
  • اختصار الدالة يزيل كلمة function لصيغة أنظف
  • أسماء الخصائص المحسوبة تستخدم التعبيرات في أقواس مربعة [expr]
  • يمكن دمج جميع الميزات لأنماط إنشاء كائنات قوية
  • الصيغ المحسّنة تعمل بشكل رائع مع التفكيك وعوامل النشر
  • استخدم اختصار الدالة (وليس الدوال السهمية) عندما تحتاج إلى سياق this
التالي: في الدرس التالي، سنستكشف المعاملات الافتراضية وكيف تبسط تعريفات الدوال!

ES
Edrees Salih
منذ 15 ساعة

We are still cooking the magic in the way!