Kodax

ES6+ الميزات الحديثة — JavaScript الأساسيات

ES6+ الميزات الحديثة

Destructuring المتقدم

// مصفوفة متداخلة
const [a, [b, c]] = [1, [2, 3]];

// تبديل القيم
let x = 1, y = 2;
[x, y] = [y, x];

// تجاهل عناصر
const [first, , third] = [1, 2, 3];

// كائن متداخل
const response = { user: { name: "سارة", address: { city: "بغداد" } } };
const { user: { name, address: { city } } } = response;

// مع إعادة تسمية وقيمة افتراضية
const user = {};  // لا يوجد name
const { name: userName = "زائر" } = user;  // userName = "زائر"

Template Literals المتقدم

// Tagged Templates
function highlight(strings, ...values) {
  return strings.reduce((acc, str, i) => {
    return acc + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
  }, '');
}

const name = "أحمد";
const result = highlight`مرحباً ${name}!`;
// مرحباً <mark>أحمد</mark>!

// SQL Query Builder
function sql(strings, ...values) {
  return {
    query: strings.join('?'),
    params: values
  };
}

const id = 5;
const query = sql`SELECT * FROM users WHERE id = ${id}`;

Symbols

// إنشاء Symbol
const id = Symbol('id');
const id2 = Symbol('id');
console.log(id === id2); // false

// استخدام كمفتاح
const user = {
  name: "أحمد",
  [id]: 123
};

console.log(user[id]); // 123
console.log(Object.keys(user)); // ["name"] - Symbol مخفي

// Well-Known Symbols
class MyArray extends Array {
  static get [Symbol.species]() {
    return Array;
  }
}

// Symbol.iterator
const range = {
  start: 1,
  end: 5,
  [Symbol.iterator]() {
    let current = this.start;
    const end = this.end;
    return {
      next() {
        if (current <= end) {
          return { value: current++, done: false };
        }
        return { done: true };
      }
    };
  }
};

for (const num of range) {
  console.log(num); // 1, 2, 3, 4, 5
}

Generators

function* numberGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = numberGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// Generator لانهائي
function* infiniteCounter() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

// Generator مع async
async function* asyncGenerator() {
  yield await fetch('/api/1');
  yield await fetch('/api/2');
}

Proxy و Reflect

const handler = {
  get(target, prop) {
    console.log(`Reading ${prop}`);
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    console.log(`Setting ${prop} = ${value}`);
    return Reflect.set(target, prop, value);
  }
};

const user = new Proxy({ name: "أحمد" }, handler);
console.log(user.name); // Reading name, أحمد
user.age = 25;          // Setting age = 25

// Validation Proxy
const validator = {
  set(target, prop, value) {
    if (prop === 'age' && typeof value !== 'number') {
      throw new TypeError('Age must be a number');
    }
    return Reflect.set(target, prop, value);
  }
};

Map و Set

// Map - مفاتيح من أي نوع
const map = new Map();
map.set('name', 'أحمد');
map.set(1, 'رقم');
map.set({ id: 1 }, 'كائن');

console.log(map.get('name')); // أحمد
console.log(map.size);        // 3
map.has('name');              // true
map.delete('name');
map.clear();

// Set - قيم فريدة فقط
const set = new Set([1, 2, 2, 3, 3, 3]);
console.log([...set]); // [1, 2, 3]

set.add(4);
set.has(1);    // true
set.delete(1);
set.size;      // 3

// WeakMap و WeakSet
const weakMap = new WeakMap(); // مفاتيح كائنات فقط، garbage collected
const weakSet = new WeakSet(); // قيم كائنات فقط

Optional Chaining و Nullish Coalescing

// Optional Chaining
const user = {
  profile: {
    address: {
      city: "بغداد"
    }
  }
};

console.log(user?.profile?.address?.city);    // بغداد
console.log(user?.profile?.phone?.number);    // undefined
console.log(user?.getAddress?.());            // undefined

// Nullish Coalescing
const value = null ?? "default";    // "default"
const value2 = 0 ?? "default";      // 0
const value3 = "" ?? "default";     // ""
const value4 = undefined ?? "default"; // "default"

// مع Optional Chaining
const city = user?.profile?.address?.city ?? "غير محدد";
// Destructuring متقدم
const user = {
  name: "أحمد",
  address: { city: "بغداد", country: "العراق" }
};

const { name, address: { city } } = user;
console.log(`${name} من ${city}`);

// Map
const scores = new Map();
scores.set("أحمد", 95);
scores.set("محمد", 88);

for (const [name, score] of scores) {
  console.log(`${name}: ${score}`);
}

// Set - إزالة التكرار
const numbers = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(numbers)];
console.log("فريدة:", unique);

// Generator
function* countdown(n) {
  while (n > 0) {
    yield n--;
  }
}

for (const num of countdown(5)) {
  console.log(num);
}
اختبر فهمك