5 نصائح JavaScript احترافية لتعزيز إنتاجيتك وتوفير الوقت
لطالما راودتني فكرة مشاركة خبراتي البرمجية عبر مقاطع الفيديو، ولكن حاجز اللغة الإنجليزية كان يمثل تحديًا. ومع ذلك، أثناء تحضيري لسلسلة من نصائح JavaScript لبدء رحلتي على YouTube، قمت بتجميع هذه القائمة من الحيل البرمجية التي توفر الوقت والجهد. آمل أن تجدوا فيها الفائدة التي وجدتها أنا شخصيًا. في هذا المقال، سأشارككم 5 نصائح JavaScript عملية ومفيدة للغاية (هل أنتم مستعدون للتعمق؟). بعض هذه النصائح متوفرة الآن على قناتي في YouTube 📹!
فك ترميز الكائنات (Object Destructuring): تبسيط استخراج البيانات
يُعد فك ترميز الكائنات (Object Destructuring) ميزة قوية قُدمت في إصدار ES6 من JavaScript. بمجرد إتقانها، ستصبح أداة أساسية في عملك اليومي، حيث تساعدك على معالجة ثلاث مشكلات رئيسية تواجهك عند التعامل مع الكائنات:
- التكرار (Repetition): في كل مرة ترغب فيها باستخراج خاصية واحدة من كائن وإنشاء متغير جديد لها، فإنك تكتب سطرًا جديدًا من الكود.
- سهولة الوصول (Accessibility): للوصول إلى خاصية معينة داخل كائن، يتوجب عليك كتابة المسار الكامل إليها (على سبيل المثال:
user.firstNameأوuser.family.sister). - الاستخدام الفعال (Usage): عند إنشاء دالة جديدة وتكون بحاجة للعمل على خاصية واحدة فقط من كائن معين، فإن تمرير الكائن بأكمله قد يكون غير ضروري.
بعد أن تعرفت على هذه المشكلات الثلاث عند التعامل مع الكائنات، كيف تعتقد أنه يمكنك حلها بفعالية؟
حل مشكلة التكرار باستخدام فك الترميز
لنبدأ بمثال يوضح المشكلة التقليدية لاستخراج الخصائص:
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
};
// الطريقة التقليدية: كل خاصية تتطلب سطرًا منفصلاً
const firstName = user.firstName;
const lastName = user.lastName;
const password = user.password;
// ملاحظة: عرض كلمة المرور بهذه الطريقة غير آمن!
console.log(firstName, lastName, password);
باستخدام فك ترميز الكائنات، يمكنك تبسيط هذه العملية بشكل كبير:
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
};
// باستخدام فك الترميز، نستخرج الخصائص في سطر واحد
const { firstName, lastName, password } = user;
console.log(firstName, lastName, password);
// الناتج: 'John', 'Doe', '123'
فك الترميز هو عملية استخلاص خاصية من كائن بناءً على مفتاحها. عندما تضع مفتاحًا موجودًا في كائنك بين قوسين متعرجين (مثل { firstName })، فإنك تخبر JavaScript: “أريد إنشاء متغير يحمل نفس اسم هذه الخاصية، أي متغير firstName لخاصية firstName في كائني.”
ملاحظة هامة: لكي يعمل فك الترميز بشكل صحيح، يجب عليك دائمًا استخدام مفتاح موجود بالفعل في الكائن، وإلا فلن تنجح العملية.
تبسيط الوصول إلى الخصائص المتداخلة
عند التعامل مع الكائنات المتداخلة (nested objects)، قد يصبح الوصول إلى الخصائص أمرًا متكررًا ومضيعة للوقت. إليك كيف يحل فك الترميز هذه المشكلة:
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
family: {
sister: {
firstName: "Maria",
},
},
};
// الوصول إلى الكائن المتداخل 'sister' واستخراج خاصية 'firstName'
const { firstName } = user.family.sister;
console.log(firstName);
// الناتج: 'Maria'
باستخدام فك الترميز، يمكنك تقليل مسار الوصول إلى الخاصية المتداخلة إلى متغير واحد فقط في سطر واحد من الكود، مما يجعل الكود أكثر نظافة وسهولة في القراءة.
تحسين استخدام الخصائص في الدوال
تخيل أن لديك دالة تحتاج فقط إلى خاصية واحدة من كائن. بدلاً من تمرير الكائن بأكمله أو إنشاء متغير مؤقت، يمكنك استخدام فك الترميز مباشرة في تعريف معلمات الدالة. هذه الممارسة شائعة جدًا إذا كنت تعمل مع أطر عمل مثل React.
function getUserFirstName({ firstName }) {
return firstName;
}
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
};
console.log(getUserFirstName(user));
// الناتج: 'John'
في المثال أعلاه، الدالة getUserFirstName تستخدم فقط خاصية firstName من الكائن. بدلاً من تمرير الكائن user كاملاً، قمنا بفك ترميز المعلمة مباشرة في تعريف الدالة، مما يجعل الكود أكثر وضوحًا وتركيزًا على الخاصية المطلوبة.
دمج الكائنات بكفاءة باستخدام عامل الانتشار (Spread Operator)
في عالم البرمجة، غالبًا ما تواجه تحديات تتعلق بمعالجة هياكل البيانات. بفضل عامل الانتشار (Spread Operator) الذي قُدم في ES6، أصبحت عمليات دمج الكائنات والمصفوفات أكثر سهولة ومرونة.
لنتخيل أن لدينا كائنين منفصلين:
user: كائن يحتوي على معلومات عامة عن المستخدم.userJob: كائن يحتوي على معلومات وظيفية للمستخدم.
هدفنا هو إنشاء كائن واحد يجمع جميع خصائص هذين الكائنين.
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
};
const userJob = {
jobName: "Developer",
jobCountry: "France",
jobTimePerWeekInHour: "35",
};
// دمج الكائنين باستخدام عامل الانتشار
const myNewUserObject = { ...user, ...userJob };
console.log(myNewUserObject);
// الناتج:
/*
{
firstName: 'John',
lastName: 'Doe',
password: '123',
jobName: 'Developer',
jobCountry: 'France',
jobTimePerWeekInHour: '35'
}
*/
باستخدام عامل الانتشار (...)، يمكننا استخلاص جميع خصائص كائن واحد ونشرها داخل كائن آخر، مما يتيح لنا دمجها بسلاسة. هذا لا يقوم بإنشاء مرجع جديد للكائن الأصلي، بل ينشئ نسخة جديدة بخصائص مدمجة.
يمكنك أيضًا استخدامه لنسخ كائن بشكل سطحي (shallow copy) إلى كائن جديد:
const user = {
firstName: "John",
lastName: "Doe",
password: "123",
};
const myNewUserObject = {
...user,
// هنا نقوم باستخلاص جميع خصائص الكائن 'user'
// (firstName, lastName, password)
// وإرسالها إلى كائن جديد فارغ {}
};
console.log(myNewUserObject);
// الناتج: { firstName: 'John', lastName: 'Doe', password: '123' }
دمج المصفوفات بسهولة باستخدام عامل الانتشار
تمامًا كما هو الحال مع الكائنات، يوفر عامل الانتشار (Spread Operator) طريقة فعالة لدمج المصفوفات أو استخلاص عناصرها إلى مصفوفة جديدة.
لنفترض أن لدينا مصفوفتين من الأسماء ونريد دمجهما في مصفوفة واحدة:
const girlNames = ["Jessica", "Emma", "Amandine"];
const boyNames = ["John", "Terry", "Alexandre"];
// دمج المصفوفتين باستخدام عامل الانتشار
const namesWithSpreadSyntax = [...girlNames, ...boyNames];
console.log(namesWithSpreadSyntax);
// الناتج: ['Jessica', 'Emma', 'Amandine', 'John', 'Terry', 'Alexandre']
عامل الانتشار (...) يقوم باستخراج جميع العناصر من مصفوفة وإضافتها إلى مصفوفة أخرى، مما يسهل عمليات الدمج والنسخ. يمكنك أيضًا استخدامه لإنشاء نسخة جديدة من مصفوفة:
const girlNames = ["Jessica", "Emma", "Amandine"];
const newNewArray = [
...girlNames, // نقوم باستخلاص عناصر 'girlNames'
// وإرسالها إلى مصفوفة جديدة []
];
console.log(newNewArray);
// الناتج: ['Jessica', 'Emma', 'Amandine']
إزالة العناصر المكررة من المصفوفات: مقارنة بين الطرق
نظرًا لأن المصفوفات هي قوائم، فمن الشائع أن تحتوي على عناصر ذات قيم متطابقة. إذا كنت ترغب في إزالة هذه التكرارات من مصفوفتك، يمكنك اتباع إحدى الطريقتين التاليتين. إحداهما هي طريقة حديثة ومختصرة بفضل ES6، بينما الأخرى هي الطريقة التقليدية التي سأعرضها للمقارنة.
إزالة التكرارات بالطريقة التقليدية (قبل ES6)
قبل ظهور ES6، كانت إحدى الطرق الشائعة لإزالة التكرارات تعتمد على دالة filter() مع دالة indexOf(). لنلقِ نظرة على المثال التالي:
const animals = ["owl", "frog", "canary", "duck", "duck", "goose", "owl"];
// استخدام دالة filter و indexOf لإزالة التكرارات
const uniqueAnimalsWithFilter = animals.filter(
(animal, index, array) => array.indexOf(animal) === index
);
console.log(uniqueAnimalsWithFilter);
// الناتج: ['owl', 'frog', 'canary', 'duck', 'goose']
في هذا المثال، نهدف إلى تنظيف مصفوفة animals من أي عناصر مكررة. نقوم بذلك باستخدام دالة filter() التي تمر على جميع عناصر المصفوفة. لكل عنصر، تقوم indexOf() بإرجاع أول فهرس (index) يظهر فيه هذا العنصر في المصفوفة الأصلية. إذا كان هذا الفهرس هو نفسه الفهرس الحالي للعنصر الذي تعالجه دالة filter()، فهذا يعني أننا نتعامل مع أول ظهور لهذا العنصر (أي أنه ليس مكررًا بعد)، وبالتالي يتم الاحتفاظ به. أما إذا كان الفهرس مختلفًا، فهذا يعني أن العنصر قد ظهر سابقًا، ويتم تجاهله.
بهذه الطريقة، تقوم دالة filter() بإنشاء مصفوفة جديدة تحتوي فقط على العناصر الفريدة.
إزالة التكرارات بالطريقة الحديثة (باستخدام Set و Spread Operator)
بينما الطريقة التقليدية مفيدة للفهم، إلا أنها قد تكون طويلة ومعقدة بعض الشيء. لحسن الحظ، قدم ES6 طريقة أكثر إيجازًا وفعالية لإزالة التكرارات باستخدام الكائن Set وعامل الانتشار.
const animals = ["owl", "frog", "canary", "duck", "duck", "goose", "owl"];
// الطريقة الحديثة: سطر واحد لإزالة التكرارات
const uniqueAnimalsWithSet = [...new Set(animals)];
console.log(uniqueAnimalsWithSet);
// الناتج: ['owl', 'frog', 'canary', 'duck', 'goose']
لفهم كيفية عمل هذه الطريقة، دعنا نقسمها إلى خطوات:
// 1. تعريف المصفوفة الأصلية
const animals = ["owl", "frog", "canary", "duck", "duck", "goose", "owl"];
// 2. تحويل المصفوفة إلى كائن Set
// كائن Set يخزن فقط القيم الفريدة تلقائيًا
const animalsSet = new Set(animals);
console.log(animalsSet);
// الناتج: Set { 'owl', 'frog', 'canary', 'duck', 'goose' }
// 3. تحويل كائن Set الفريد مرة أخرى إلى مصفوفة باستخدام عامل الانتشار
const uniqueAnimalsWithSet = [...animalsSet];
console.log(uniqueAnimalsWithSet);
// الناتج: ['owl', 'frog', 'canary', 'duck', 'goose']
هنا، نقوم بتحويل مصفوفة animals إلى كائن Set، وهو نوع خاص من الكائنات في ES6 يتميز بأنه يخزن مجموعة من القيم الفريدة فقط. بعد الحصول على كائن Set الذي يحتوي على القيم الفريدة، نستخدم عامل الانتشار (...) لتحويله مرة أخرى إلى مصفوفة. نظرًا لأن كائن Set يضمن حصرية القيم، فإن المصفوفة الجديدة الناتجة ستحتوي أيضًا على قيم فريدة فقط.
ملاحظة: على الرغم من أن Set يخزن قيمًا فريدة، إلا أنه ليس مصفوفة (Array) بحد ذاته. لذلك، نحتاج إلى خطوة إضافية لتحويله إلى مصفوفة إذا كنا بحاجة إلى وظائف المصفوفة.
استخدام عامل التشغيل الثلاثي (Ternary Operator) لتبسيط الشروط
هل سمعت من قبل عن طريقة لكتابة الشروط البسيطة في سطر واحد فقط؟ إذا لم يكن الأمر كذلك، فقد حان الوقت لتبسيط الكثير من كتل if و else في كودك وتحويلها إلى عمليات ثلاثية موجزة. لنبدأ بمثال يوضح كيفية التحقق من قيمة متغير وعرض مخرجات مشروطة.
const colour = "blue";
if (colour === "blue") {
console.log(`It's blue!`);
} else {
console.log(`It's not blue!`);
}
هذا المثال هو حالة نموذجية يمكنك فيها استخدام عامل التشغيل الثلاثي لتقليص هذه الأسطر الخمسة من if و else إلى سطر واحد فقط!
const colour = "blue";
// [الشرط] ? [إذا كان الشرط صحيحًا] : [إذا كان الشرط خاطئًا]
colour === "blue" ? console.log(`It's blue!`) : console.log(`It's not blue!`);
يحل عامل التشغيل الثلاثي محل عبارات if و else للشروط البسيطة والمختصرة. ومع ذلك، ملاحظة هامة: لا يُنصح بإنشاء شروط معقدة باستخدام عامل التشغيل الثلاثي، حيث يمكن أن يقلل ذلك من قابلية قراءة الكود ويجعله صعب الفهم.
إليك مثال آخر يوضح استخدام عامل التشغيل الثلاثي، ولكن هذه المرة ضمن عبارة return لدالة:
function sayHelloToAnne(name) {
return name === "Anne" ? "Hello, Anne!" : "It's not Anne!";
}
console.log(sayHelloToAnne("Anne"));
// الناتج: 'Hello, Anne!'
console.log(sayHelloToAnne("Gael"));
// الناتج: "It's not Anne!"
في هذا المثال، تحدد الدالة sayHelloToAnne رسالة الترحيب بناءً على ما إذا كان الاسم المدخل هو "Anne" أم لا، كل ذلك في سطر واحد أنيق.
الخلاصة التقنية
لقد استعرضنا في هذا المقال خمس نصائح برمجية متقدمة في JavaScript، مستفيدين بشكل كبير من ميزات ES6. بدءًا من تبسيط استخراج البيانات باستخدام Object Destructuring، مرورًا بدمج الكائنات والمصفوفات بكفاءة عبر Spread Operator، وصولاً إلى إزالة التكرارات بأسلوب حديث باستخدام Set، واختصار الشروط المعقدة بعامل التشغيل الثلاثي Ternary Operator. هذه التقنيات لا تقتصر فقط على توفير الوقت وكتابة كود أنظف وأكثر قابلية للقراءة، بل تساهم أيضًا في تحسين أداء التطبيقات وزيادة إنتاجية المطور. إن إتقان هذه المفاهيم يعد خطوة أساسية نحو أن تصبح مطور JavaScript أكثر احترافية وفعالية في بيئات العمل الحديثة.