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);
}
اختبر فهمك