تستمر JavaScript في التطور، ومع تقديم ES13 (ECMAScript 2022)، هناك العديد من الميزات الجديدة التي يجب أن يكون المطورون على دراية بها لكتابة تعليمات برمجية أكثر كفاءة وحداثة. في هذه المقالة، سنتناول عشرة من أكثر الميزات تأثيرًا في ES13 والتي يمكنها تحسين سير عمل التطوير لديك.
في السابق، كان بإمكانك فقط استخدام وظائف الانتظار داخل غير المتزامنة. هذا يعني أنه إذا كنت بحاجة إلى استخدام الانتظار، فسيتعين عليك تغليف التعليمات البرمجية الخاصة بك داخل وظيفة غير متزامنة، حتى لو لم تكن بقية الوحدة الخاصة بك تتطلب ذلك.
// Without top-level await (Before ES13) async function fetchData() { const data = await fetch('/api/data'); return data.json(); } fetchData().then(console.log);
مع ES13، يمكنك الآن استخدام الانتظار في المستوى الأعلى من الوحدة الخاصة بك، مما يلغي الحاجة إلى وظيفة إضافية غير متزامنة.
// With top-level await (ES13) const data = await fetch('/api/data'); console.log(await data.json());
قبل ES13، لم تكن فئات JavaScript تحتوي على حقول أو أساليب خاصة حقيقية. غالبًا ما يستخدم المطورون اصطلاحات التسمية مثل الشرطة السفلية أو الإغلاق لمحاكاة الخصوصية، لكن هذه الأساليب لم تكن خاصة حقًا.
// Simulating private fields (Before ES13) class Person { constructor(name) { this._name = name; // Conventionally "private" } _getName() { return this._name; } greet() { return `Hello, ${this._getName()}!`; } } const john = new Person('John'); console.log(john._getName()); // Accessible, but intended to be private
يقدم ES13 أساليب ووصولات خاصة حقيقية باستخدام البادئة #، مما يضمن عدم إمكانية الوصول إليها خارج الفصل.
// Private instance methods and fields (ES13) class Person { #name = ''; constructor(name) { this.#name = name; } #getName() { return this.#name; } greet() { return `Hello, ${this.#getName()}!`; } } const john = new Person('John'); console.log(john.greet()); // Hello, John! console.log(john.#getName()); // Error: Private field '#getName' must be declared in an enclosing class
قبل ES13، تم تحديد الحقول والأساليب الثابتة عادةً خارج نص الفصل، مما أدى إلى كود أقل تماسكًا.
// Static fields outside class body (Before ES13) class MathUtilities {} MathUtilities.PI = 3.14159; MathUtilities.calculateCircumference = function(radius) { return 2 * MathUtilities.PI * radius; }; console.log(MathUtilities.PI); // 3.14159 console.log(MathUtilities.calculateCircumference(5)); // 31.4159
يتيح لك ES13 تحديد الحقول والأساليب الثابتة مباشرة داخل نص الفصل الدراسي، مما يحسن إمكانية القراءة والتنظيم.
// Static fields and methods inside class body (ES13) class MathUtilities { static PI = 3.14159; static calculateCircumference(radius) { return 2 * MathUtilities.PI * radius; } } console.log(MathUtilities.PI); // 3.14159 console.log(MathUtilities.calculateCircumference(5)); // 31.4159
غالبًا ما يتم دمج العوامل المنطقية (&&، ||، ??) والتخصيص يدويًا في عبارات مطولة، مما يؤدي إلى تعليمات برمجية أكثر تعقيدًا.
// Manually combining logical operators and assignment (Before ES13) let a = 1; let b = 0; a = a && 2; // a = 2 b = b || 3; // b = 3 let c = null; c = c ?? 4; // c = 4 console.log(a, b, c); // 2, 3, 4
يقدم ES13 عوامل التعيين المنطقية، والتي تجمع بين العمليات المنطقية والتخصيص في بناء جملة موجز.
// Logical assignment operators (ES13) let a = 1; let b = 0; a &&= 2; // a = a && 2; // a = 2 b ||= 3; // b = b || 3; // b = 3 let c = null; c ??= 4; // c = c ?? 4; // c = 4 console.log(a, b, c); // 2, 3, 4
لم تكن المراجع والنهائيات الضعيفة مدعومة أصلاً في JavaScript، مما يجعل من الصعب إدارة الموارد في حالات معينة، خاصة مع التطبيقات واسعة النطاق التي تتعامل مع كائنات باهظة الثمن.
// No native support for weak references (Before ES13) // Developers often had to rely on complex workarounds or external libraries.
يقدم ES13 WeakRef وFinalizationRegistry، مما يوفر دعمًا أصليًا للمراجع الضعيفة ومهام التنظيف بعد جمع البيانات المهملة.
// WeakRefs and FinalizationRegistry (ES13) let obj = { name: 'John' }; const weakRef = new WeakRef(obj); console.log(weakRef.deref()?.name); // 'John' obj = null; // obj is eligible for garbage collection setTimeout(() => { console.log(weakRef.deref()?.name); // undefined (if garbage collected) }, 1000); const registry = new FinalizationRegistry((heldValue) => { console.log(`Cleanup: ${heldValue}`); }); registry.register(obj, 'Object finalized');
لم يكن التحقق مما إذا كان الكائن يحتوي على حقل خاص أمرًا سهلاً، حيث لم تكن الحقول الخاصة مدعومة أصلاً. كان على المطورين الاعتماد على أساليب الحل البديل، مثل التحقق من الخصائص العامة أو استخدام عمليات التحقق.
// Checking for private fields using workarounds (Before ES13) class Car { constructor() { this.engineStarted = false; // Public field } startEngine() { this.engineStarted = true; } static isCar(obj) { return obj instanceof Car; // Not reliable for truly private fields } } const myCar = new Car(); console.log(Car.isCar(myCar)); // true
مع ES13، يمكنك الآن التحقق مباشرة مما إذا كان الكائن يحتوي على حقل خاص باستخدام بناء الجملة #، مما يجعله أسهل وأكثر موثوقية.
// Ergonomic brand checks for private fields (ES13) class Car { #engineStarted = false; startEngine() { this.#engineStarted = true; } static isCar(obj) { return #engineStarted in obj; } } const myCar = new Car(); console.log(Car.isCar(myCar)); // true
يتضمن الوصول إلى العناصر من المصفوفات استخدام تدوين الأقواس مع فهرس، وبالنسبة للمؤشرات السالبة، كان عليك حساب الموضع يدويًا.
// Accessing array elements (Before ES13) const arr = [1, 2, 3, 4, 5]; console.log(arr[arr.length - 1]); // 5 (last element)
يسمح لك الأسلوب at() بالوصول إلى عناصر المصفوفة باستخدام المؤشرات الموجبة والسالبة بشكل أكثر سهولة.
// Accessing array elements with `at()` (ES13) const arr = [1, 2, 3, 4, 5]; console.log(arr.at(-1)); // 5 (last element) console.log(arr.at(0)); // 1 (first element)
للتحقق مما إذا كان الكائن له خاصية خاصة به (غير موروثة)، يستخدم المطورون عادةً Object.prototype.hasOwnProperty.call() أو obj.hasOwnProperty().
// Checking own properties (Before ES13) const obj = { a: 1 }; console.log(Object.prototype.hasOwnProperty.call(obj, 'a')); // true console.log(obj.hasOwnProperty('a')); // true
يعمل الأسلوب Object.hasOwn() الجديد على تبسيط عملية التحقق هذه، وتوفير صيغة أكثر إيجازًا وقابلية للقراءة.
// Checking own properties with `Object.hasOwn()` (ES13) const obj = { a: 1 }; console.log(Object.hasOwn(obj, 'a')); // true
يتطلب تحويل أزواج القيمة الرئيسية (على سبيل المثال، من الخريطة أو المصفوفات) إلى كائن التكرار والإنشاء اليدوي.
// Creating an object from entries (Before ES13) const entries = [['name', 'John'], ['age', 30]]; const obj = {}; entries.forEach(([key, value]) => { obj[key] = value; }); console.log(obj); // { name: 'John', age: 30 }
يعمل Object.fromEntries() على تبسيط إنشاء الكائنات من أزواج القيمة الرئيسية.
// Creating an object with `Object.fromEntries()` (ES13) const entries = [['name', 'John'], ['age', 30]]; const obj = Object.fromEntries(entries); console.log(obj); // { name: 'John', age: 30 }
لم تكن قيمة هذا في المستوى الأعلى للوحدة محددة، مما أدى إلى حدوث ارتباك عند نقل التعليمات البرمجية من البرامج النصية إلى الوحدات النمطية.
// Global `this` (Before ES13) console.log(this); // undefined in modules, global object in scripts
يوضح ES13 أن قيمة هذا في المستوى الأعلى للوحدة تكون دائمًا غير محددة، مما يوفر الاتساق بين الوحدات والبرامج النصية.
// Global `this` in modules (ES13) console.log(this); // undefined
تم تصميم ميزات ES13 هذه لجعل كود JavaScript الخاص بك أكثر كفاءة وقابلية للقراءة والصيانة. ومن خلال دمج هذه العناصر في ممارسات التطوير الخاصة بك، يمكنك الاستفادة من أحدث التطورات في اللغة لإنشاء تطبيقات حديثة وعالية الأداء.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3