اذهب إلى المحتوى

الميزات الجديدة في ES6: القوالب Templates والكائنات


محمد أحمد العيل

تعرّفنا في مقال سابق على ميزات جديدة في الإصدار ES6 من جافاسكريبت. سنتابع في هذا المقال الحديث عن الميزات الأكثر استخداما من هذا الإصدار وذلك بتناول الإضافات الجديدة التالية:

  • المُعاملان restوspread.
  • تحسينات على الكائنات.
  • القوالب Templates.

المعاملان rest وspread

يبدو المعاملان rest وspread متشابهين، ويُشار إلى كليهما بثلاث نقاط .... يختلف عمل المعاملين تبعا لطريقة استخدامهما.

المعامل rest

يعمل rest حرفيا على أخذ بقيّة الشيء ووضعها ضمن مصفوفة. يحوّل المعامل لائحة من المعاملات المحدّدة بفاصلة إلى مصفوفة.

فلنر أمثلة عملية على rest. فلنتخيّل أن لدينا دالة باسم add تجمع المعطيات المُمرَّرة لها:

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55

نعتمد في الإصدار ES5 على المتغيّر arguments في كل مرة نحتاج فيها للتعامل مع دالة تأخذ عددا غير محدّد من المعاملات. المتغيّر arguments هو من النوع Symbol الشبيه بالمصفوفات Array.

function sum () {
  console.log(arguments)
}

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

03_arguments.png

إحدى الطرق التي يمكن استخدامها لجمع قيم arguments هي تحويلها إلى مصفوفة Array باستخدام Array.prototype.slice.call(arguments) ثم المرور على كل عدد باستخدام تابع مصفوفة مثل forEach وreduce.

من السهل استخدام forEach لهذا الغرض، لذا سأشرح استخدام reduce:

function sum () {
  let argsArray = Array.prototype.slice.call(arguments)
  return argsArray.reduce(function(sum, current) {
    return sum + current
  }, 0)
}

يتيح لنا المعامل rest جعل جميع القيم المفصولة بفاصلة في مصفوفة مباشرة:

const sum = (...args) => args.reduce((sum, current) => sum + current, 0)

أو إن أردنا التقليل من استخدام الدوال السهمية:

function sum (...args) {
  return args.reduce((sum, current) => sum + current, 0)
}

عرّجنا سريعا عند الحديث عن تفكيك المصفوفات على المعامل rest بسرعة. حاولنا حينها تفكيك المصفوفة scores إلى القيم الثلاث الأعلى:

let scores = ['98', '95', '93', '90', '87', '85']
let [first, second, third] = scores

console.log(first) // 98
console.log(second) // 95
console.log(third) // 93

إن رغبنا في الحصول على بقية النتائج فبإمكاننا جعلها في مصفوفة مستقلة بالمعامل rest:

let scores = ['98', '95', '93', '90', '87', '85']
let [first, second, third, ...restOfScores] = scores

console.log(restOfScores) // [90, 97, 95]

تذكّر دائما - لتحنب الخلط - أن المعامل rest يجعل كل شيء في مصفوفة؛ ويظهر في معاملات الدوال وأثناء تفكيك المصفوفات.

المعامل spread

يعمل المعامل spread بطريقة معاكسة لعمل rest. يأخذ المعامل مصفوفة ويوزّعها على لائحة معاملات يُفصَل بين قيمها بفاصلة:

let array = ['one', 'two', 'three']

// نتيجة التعليمتين التاليتين متطابقة
console.log(...array) // one two three
console.log('one', 'two', 'three') // one two three

يُستخدَم المعامل spread غالبا لجمع المصفوفات بطريقة تسهّل قراءتها وفهمها.

نريد على سبيل المثال جمع المصفوفات التالية:

let array1 = ['one', 'two']
let array2 = ['three', 'four']
let array3 = ['five', 'six']

يُستخدَم التابع Array.concat في الإصدارات القديمة من جافاسكريبت لجمع عدد غير محدَّد من المصفوفات:

let combinedArray = array1.concat(array2).concat(array3)
console.log(combinedArray) // ['one', 'two', 'three', 'four', 'five', 'six']

يتيح المعامل spread توزيع قيم المصفوفات على مصفوفة جديدة على النحو التالي:

let combinedArray = [...array1, ...array2, ...array3]
console.log(combinedArray) // ['one', 'two', 'three', 'four', 'five', 'six']

يُستخدَم المعامل spread كذلك لحذف عنصُر من مصفوفة دون التعديل عليها. تُستخدَم هذه الطريقة كثيرا في Redux (يشرح هذا الفيديو) كيف يفعلون ذلك.

تحسينات على الكائنات

الكائنات من الأمور التي يجدر بكلّ مبرمج جافاسكريبت التعوّد عليها. للتذكير؛ تبدو الكائنات بالهيئة التالية:

const anObject = {
  property1: 'value1',
  property2: 'value2',
  property3: 'value3',
}

يضيف الإصدار ES6 ثلاث ميزات جديدة للكائنات في جافاسكريبت:

  • اختصار قيم الخاصيّات Properties،
  • اختصارات للتوابع Methods،
  • إمكانية استخدام أسماء محسوبة للخاصيّات.

سنعرّج على كل واحدة من هذه الميزات.

اختصار قيم الخاصيّات

هل سبق لك ملاحظة أنك تسند أحيانا متغيّرا إلى خاصية كائن تشترك معه في الاسم؟ شيء من قبيل:

const fullName = 'Zell Liew'

const Zell = {
  fullName: fullName
}

قد ترغب في طريقة أكثر اختصارا من السابق بما أن الخاصيّة fullNameتساوي قيمة المتغيّر fullName. تساعد ميزة اختصار قيم الخاصيّات التي يضيفها الإصدار ES6 في تقليل الشفرة اللازمة لكتابة الكائنات عندما يوافق اسمُ المتغيّر اسمَ الخاصيّة:

const fullName = 'Zell Liew'

// استخدام ميزة الاختصار في ES6
const Zell = {
  fullName
}

// يُترجَم الاختصار في الخلفية إلى ...
const Zell = {
  fullName: fullName
}

اختصارات التوابع

التوابع هي خاصيّات بصيغة دوالّ. تُسمّى هذه الخاصيّات توابع لأنها دوال. في ما يلي مثال على تابع:

const anObject = {
  aMethod: function () { console.log("I'm a method!~~")}
}

يتيح الإصدار ES6 كتابة التوابع بطريقة مختصرة. يمكننا حذف الكلمة المفتاحية function ولن يتغيّر شيء:

const anObject = {
  // حسب ES6
  aShorthandMethod (arg1, arg2) {},

  // حسب ES5
  aLonghandMethod: function (arg1, arg2) {},
}

استخدم هذه الميزة لاختصار توابع الكائنات ولا تلجأ إلى الدوال السهمية لكتابة التوابع (راجع الدوال السهمية في مقال سابق).

const dontDoThis = {
  // تجنّب هذا
  arrowFunction: () => {}
}

أسماء محسوبة للخاصيّات

تحتاج أحيانا إلى أسماء متغيّرة (ديناميكية) لخاصيّات الكائن. في هذه الحالة ننشئ متغيّرا نضع فيه اسم الخاصيّة الديناميكية. تضطرّ في الإصدارات القديمة من جافاسكريبت لإنشاء الكائن ثم إسناد الخاصيّة على النحو التالي:

// متغيّر لحفظ اسم الخاصيّة الجديدة
const newPropertyName = 'smile'

// ننشئ الكائن أولا
const anObject = { aProperty: 'a value' }

// ثم نسند قيمة للخاصية الجديدة
anObject[newPropertyName] = ':D'

// إضافة خاصيّة مختلفة قليلا عن السابقة وإسناد قيمة لها
anObject['bigger ' + newPropertyName] = 'XD'

// النتيجة
// {
//   aProperty: 'a value',
//   'bigger smile': 'XD'
//   smile: ':D',
// }

ينزع الإصدار ES6 الحاجة للّف والدوران كما في المثال السابق؛ إذ أصبح بإمكانك إسناد أسماء متغيّرة للخاصيّات مباشرة أثناء إنشاء الكائن بجعل الخاصيّة المتغيّرة داخل أقواس معكوفة:

const newPropertyName = 'smile'

const anObject = {
  aProperty: 'a value',
  // أسماء متغيّرة للكائنات
  [newPropertyName]: ':D',
  ['bigger ' + newPropertyName]: 'XD',
}

// النتيجة
// {
//   aProperty: 'a value',
//   'bigger smile': 'XD'
//   smile: ':D',
// }

القوالب

التعامل مع سلاسل المحارف Strings في جافاسكريبت مزعج للغاية. رأينا مثالا على ذلك في دالة announcePlayer عند الحديث عن المعاملات المبدئية. أنشأنا في تلك الدالة سلاسل محارف فارغة ودمجناها باستخدام عامل الجمع +:

function announcePlayer (firstName, lastName, teamName) {
  console.log(firstName + ' ' + lastName + ', ' + teamName)
}

تأتي القوالب في الإصدار ES6 لتفادي هذا المشكل (كانت القوالب تُسمى سلاسل محارف القوالب Template strings في مسودات ES6).

توضع سلاسل المحارف التي نريد جعلها قالبا بين علامتيْ `. يمكن استخدام متغيّرات جافاسكريبت في القوالب داخل ماسك المكان {}$ .

هكذا يبدو الأمر:

const firstName = 'Zell'
const lastName = 'Liew'
const teamName = 'unaffiliated'

const theString = `${firstName} ${lastName}, ${teamName}`

console.log(theString)
// Zell Liew, unaffiliated

يمكنك كلك إنشاء سلاسل محارف متعدّدة الأسطُر بسهولة. تعمل الشفرة التالية دون مشكل:

const multi = `One upon a time,
In a land far far away,
there lived a witich,
who could change night into day`

يمكنك كذلك إنشاء شفرات HTML في جافاسكريبت باستخدام القوالب (ربما لا تكون هذه هي أفضل طريقة لإنشاء عناصر HTML، لكنها على كل حال أفضل من إنشاء عناصر HTML الواحد تلو الآخر).

const container = document.createElement('div')
const aListOfItems =
  `<ul>
    <li>Point number one</li>
    <li>Point number two</li>
    <li>Point number three</li>
    <li>Point number four</li>
  </ul>`

container.innerHTML = aListOfItems

document.body.append(container)

تأتي مع القوالب ميزة الوسوم Tags، وهي دوال يمكن بواسطتها التعامل مع سلاسل المحارف الموجودة في القوالب إن أردت استبدال سلسلة بأخرى.

const animal = 'lamb'

// هذه الدالة تمثّل وسما
const tagFunction = () => {
  // Do something here
}

const string = tagFunction `Mary had a little ${animal}`

عليّ الاعتراف أنه على الرغم من أن وسوم القوالب تبدو ميزة مفيدة للغاية إلا أنني لم أحتج حتى الساعة لاستخدامها.

خاتمة

تعرّفنا في هذا الدليل على أكثر ميزات الإصدار ES6 من جافاسكريبت استخداما. سيكون من المفيد التعوّد على استخدام هذه الإضافات كل ما كان ذلك ممكنا، فمن المؤكّد أنها ستجعل شفرتك البرمجية أقصر وأسهل قراءة وبالتالي تزيد من إنتاجيّتك.

ترجمة - بتصرّف - للمقال Introduction to commonly used ES6 features لصاحبه Zell.


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...