نقدم لكم ترجمة لمقال
Sukhjinder Arora المنشور على
Bits and Pieces . اكتشف تحت القط حول وظائف الترتيب الأعلى في JavaScript وبعض الوظائف الأخرى المضمنة في هذه اللغة.
الصورة بواسطة NESA من قبل صناع Unsplashعند تعلم برمجة JavaScript ، ربما صادفت مفهوم
وظائف الترتيب الأعلى . على الرغم من أن هذا المفهوم قد يبدو مخيفًا ، إلا أنه في الواقع ليس معقدًا.
بفضل القدرة على العمل مع وظائف عالية الترتيب ، تعد JavaScript مناسبة للبرمجة الوظيفية.
دالات الترتيب الأعلى شائعة في JavaScript. إذا كنت قد عملت معه لفترة ، فمن المحتمل جدًا أنك استخدمت مثل هذه الوظائف دون حتى إدراكها.
للحصول على صورة كاملة لوظائف الترتيب الأعلى ، تحتاج أولاً إلى فهم
البرمجة الوظيفية ووظائف الدرجة الأولى .
نصيحة : غالبًا ما تؤدي إعادة استخدام وظائف JavaScript إلى التكرارات. لتجنب ذلك ، استخدم
Bit (GitHub) . يمكنك بسهولة العثور على ميزات جديدة ومشاركتها وإعادة تطبيقها مع الحد الأدنى من التغييرات الإدارية. جربها ، لا تخجل.
ما هي البرمجة الوظيفية
بدون الدخول في التفاصيل ، البرمجة الوظيفية هي البرمجة التي يتم فيها تمرير بعض الدالات كوسيطات للدالات الأخرى وإرجاع الدوال الثالثة كقيم. في البرمجة الوظيفية ، نفكر ونعمل بالوظائف.
تتم البرمجة الوظيفية بلغات مثل JavaScript و Haskell و Clojure و Scala و Erlang.
ما هي ميزات الدرجة الأولى
عند تعلم العمل مع JavaScript ، سمعت على الأرجح أنه بالنسبة له ، الوظائف هي مواطنين من الدرجة الأولى. والحقيقة هي أنه في JavaScript ، كما هو الحال في أي لغة برمجة وظيفية أخرى ، تعد الوظائف كائنات.
الدالات الخاصة بـ JavaScript بشكل خاص كائنات من نوع خاص (كائنات
Function
أو
Function
). على سبيل المثال:
function greeting() { console.log('Hello World'); }
لإظهار أن الوظائف في JavaScript هي كائنات ، يمكننا القيام بشيء مثل هذا:
ملاحظة: على الرغم من أن ما ورد أعلاه يعمل بشكل جيد في JavaScript ، فلا يجب إساءة استخدامه. لا يمكنك تعيين خصائص عشوائية للمرفقات - من الأفضل استخدام الأشياء العادية.
في JavaScript ، ينطبق كل ما يمكنك القيام به مع الكيانات الأخرى ، مثل كائن أو سلسلة أو رقم على الوظائف. يمكن تمريرها ، بما في ذلك كوسيطات للوظائف الأخرى (ثم تسمى وظائف رد الاتصال أو وظائف رد الاتصال) ، وتعيينها للمتغيرات ، وما إلى ذلك. هذا هو السبب في دالات JavaScript تسمى وظائف الدرجة الأولى.
تعيين وظائف للمتغيرات
تسمح لك JavaScript بتعيين الوظائف للمتغيرات. على سبيل المثال:
const square = function(x) { return x * x; }
يمكن أيضًا نقلها. على سبيل المثال:
const foo = square;
تمرير الوظائف كوسيطة
يمكننا تمرير الدوال كحجج للدوال الأخرى. على سبيل المثال:
function formalGreeting() { console.log("How are you?"); } function casualGreeting() { console.log("What's up?"); } function greet(type, greetFormal, greetCasual) { if(type === 'formal') { greetFormal(); } else if(type === 'casual') { greetCasual(); } }
الآن ، بعد أن عرفنا ما هي وظائف الدرجة الأولى ، دعنا ننتقل إلى وظائف الترتيب الأعلى في JavaScript.
وظائف ترتيب أعلى
الدالات ذات الترتيب الأعلى هي دالات تعمل مع دالات أخرى ، أو تأخذ دالة كوسيطة ، أو ترجع دالة نتيجة لذلك.
من أمثلة الدالات عالية الترتيب المضمنة بالفعل في اللغة
Array.prototype.map
و
Array.prototype.filter
و
Array.prototype.reduce
.
وظائف النظام الأعلى في العمل
دعونا نلقي نظرة على بعض الأمثلة للوظائف المضمنة ذات الترتيب الأعلى ومقارنتها بالحلول التي لا تستخدم فيها الوظائف ذات الترتيب الأعلى.
Array.prototype.mapينشئ أسلوب
map()
صفيفًا جديدًا نتيجة استدعاء الوظيفة الممررة لكل عنصر من عناصر الصفيف الأولي. تأخذ طريقة
map()
كل قيمة من وظائف رد الاتصال وتنشئ مصفوفة جديدة باستخدام هذه القيم.
تأخذ وظيفة رد الاتصال التي تم تمريرها إلى طريقة
map()
ثلاث وسيطات:
element
index
array
.
تأمل هذا مع بعض الأمثلة.
المثال رقم 1لنفترض أن لدينا مصفوفة أرقام ، ومنه نريد إنشاء مصفوفة جديدة يتم فيها مضاعفة كل رقم من الصفيف الأولي. كيف يمكننا حل هذه المشكلة بوظيفة ترتيب أعلى وبدونها؟
بدون وظيفة ترتيب أعلى: const arr1 = [1, 2, 3]; const arr2 = []; for(let i = 0; i < arr1.length; i++) { arr2.push(arr1[i] * 2); }
استخدام وظيفة
map
الترتيب الأعلى:
const arr1 = [1, 2, 3]; const arr2 = arr1.map(function(item) { return item * 2; }); console.log(arr2);
يمكن جعل الكود أقصر باستخدام وظيفة السهم.
const arr1 = [1, 2, 3]; const arr2 = arr1.map(item => item * 2); console.log(arr2);
المثال رقم 2لنفترض أن لدينا مصفوفة تحتوي على سنوات ميلاد العديد من الأشخاص ، ونريد منها إنشاء مصفوفة جديدة ستكون فيها أعمارهم.
بدون وظيفة ترتيب أعلى: const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = []; for(let i = 0; i < birthYear.length; i++) { let age = 2018 - birthYear[i]; ages.push(age); }
استخدام وظيفة
map
الترتيب الأعلى:
const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year);
Array.prototype.filterتنشئ طريقة
filter()
صفيفًا جديدًا اجتازت جميع العناصر الاختبار المحدد في الدالة التي تم تمريرها. تأخذ وظيفة رد الاتصال التي تم تمريرها إلى
filter()
ثلاث وسيطات:
element
index
array
.
تأمل هذا مع بعض الأمثلة.
المثال رقم 1تخيل أن لدينا مصفوفة تحتوي على كائنات لها خصائص "الاسم" و "العمر". نريد منه إنشاء مجموعة جديدة يتم فيها الإشارة إلى البالغين فقط (من سن الثامنة عشرة وما فوق).
بدون وظيفة ترتيب أعلى: const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = []; for(let i = 0; i < persons.length; i++) { if(persons[i].age >= 18) { fullAge.push(persons[i]); } } console.log(fullAge);
باستخدام وظيفة
filter
الدرجة الأعلى:
const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = persons.filter(person => person.age >= 18); console.log(fullAge);
Array.prototype.reduceيطبق أسلوب التصغير دالة على كل قيمة للصفيف ، ويقللها إلى قيمة واحدة. تأخذ طريقة التصغير وسيطتين:
- وظيفة رد الاتصال المراد معالجتها ؛
- معلمة
initialValue
اختيارية (الوسيطة الأولى في استدعاء الوظيفة الأولى).
تأخذ وظيفة رد الاتصال أربع وسائط:
accumulator
،
currentValue
،
currentIndex
،
sourceArray
.
إذا تم تمرير المعلمة
initialValue
، فستكون وسيطة
accumulator
مساوية
initialValue
،
currentValue
وسيطة
currentValue
هي العنصر الأول للصفيف.
إذا لم يتم تمرير المعلمة
initialValue
، فستكون وسيطة
accumulator
مساوية للعنصر الأول من الصفيف ، وسيتم أخذ العنصر الثاني للصفيف كوسيطة
currentValue
.
المثال رقم 1افترض أننا بحاجة إلى العثور على مجموع الأرقام في صفيف.
يؤدي استخدام وظيفة ترتيب أعلى إلى
reduce
:
const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; });
في كل مرة يتم فيها تطبيق دالة رد اتصال على كل قيمة من الصفيف ، تقوم وسيطة المجمع بحفظ نتيجة الإجراء السابق الذي
currentValue
الدالة ، وتأخذ قيمة
currentValue
القيمة التالية للصفيف. عند الانتهاء ، يتم تخزين النتيجة في
sum
المتغير.
بالإضافة إلى ذلك ، يمكننا تمرير هذه الوظيفة القيمة الأولية:
const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 10);
بدون وظيفة ترتيب أعلى:
const arr = [5, 7, 1, 8, 4]; let sum = 0; for(let i = 0; i < arr.length; i++) { sum = sum + arr[i]; }
كما ترون ، بمساعدة وظيفة ترتيب أعلى ، يمكن جعل الرمز أكثر دقة وأقصر وأكثر سعة.
قم بإنشاء وظيفة الترتيب الأعلى الخاصة بك
حتى هذه اللحظة ، أخذنا بعين الاعتبار العديد من وظائف الترتيب العالي المضمنة في اللغة. حان الوقت لإنشاء وظيفة الترتيب الأعلى الخاصة بك.
تخيل أن جافا سكريبت لن يكون لها طريقة
map
خاصة بها. يمكننا أن نبنيها بأنفسنا ، وبالتالي خلق وظيفتنا الخاصة من أجل نظام أعلى.
لنفترض أن لدينا مصفوفة من السلاسل ، ونريد منه إنشاء مصفوفة من التكاملات يمثل فيها كل عنصر طول السلسلة من الصفيف الأولي.
const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C']; function mapForEach(arr, fn) { const newArray = []; for(let i = 0; i < arr.length; i++) { newArray.push( fn(arr[i]) ); } return newArray; } const lenArray = mapForEach(strArray, function(item) { return item.length; });
في المثال أعلاه ، أنشأنا دالة
mapForEach
ذات الترتيب
mapForEach
، والتي تأخذ مصفوفة ووظيفة رد اتصال
fn
mapForEach
. يتم تطبيق هذه الوظيفة بشكل دوري على كل عنصر من عناصر الصفيف وتستدعي وظيفة رد الاتصال
fn
كجزء من
newArray.push
دالة
newArray.push
في كل تكرار.
تأخذ وظيفة رد الاتصال
fn
العنصر الحالي للصفيف الأولي وترجع قيمة طول هذا العنصر ، المخزنة داخل
newArray
الجديد
newArray
. بعد اكتمال التكرار ،
newArray
إرجاع صفيف
newArray
كنتيجة
lenArray
صفيف
lenArray
.
الخلاصة
لقد تعلمنا ما هي الوظائف العليا ، وفحصنا بعض الوظائف المضمنة في اللغة. لقد تعلمنا أيضًا كيفية إنشاء وظائف النظام الأعلى الخاصة بك.
باختصار ، تعمل الدوال ذات الترتيب الأعلى مثل الدالات العادية ، ولكن لديها القدرة الإضافية على تلقي وظائف أخرى كوسيطة وإعادتها نتيجة لذلك.
هذا ، في الواقع ، كل شيء. إذا وجدت هذه المقالة مفيدة ، يمكنك أيضًا متابعتي على
Medium وعلى
Twitter . لا تتردد في التعليق إذا كان لديك أي أسئلة! سأكون سعيدا للمساعدة. :)