يمكنك تحديد وظائف JavaScript بعدة طرق.
الطريقة الأولى المعتادة هي استخدام ملف function
الكلمة الأساسية:
// Function declarationfunction greet(who) {return `Hello, ${who}!`;}// Function expressionconst greet = function(who) {return `Hello, ${who}`;}
إعلان الوظيفة وتعبير الوظيفة الذي سأشير إليه كدالة عادية.
الطريقة الثانية ، المتوفرة ابتداءً من ES2015 ، هي بناء جملة دالة السهم:
const greet = (who) => {
return `Hello, ${who}!`;
}
بينما تحدد البنية العادية وصيغة الأسهم الوظائف ، متى تختار واحدة بدلاً من الأخرى؟ هذا سؤال جيد.
في هذا المنشور ، سأعرض الاختلافات الرئيسية بين الاثنين ، حتى تتمكن من اختيار الصيغة الصحيحة لاحتياجاتك.
وظيفة منتظمة
داخل وظيفة JavaScript العادية ، this
القيمة (ويعرف أيضًا باسم سياق التنفيذ) ديناميكية.
السياق الديناميكي يعني أن قيمة this
يعتمد على كيفية استدعاء الوظيفة. في JavaScript ، هناك 4 طرق يمكنك من خلالها استدعاء دالة عادية.
خلال الاحتجاج البسيط قيمة this
يساوي الكائن العالمي (أو undefined
إذا كانت الوظيفة تعمل في الوضع المتشدد):
function myFunction() {
console.log(this);
}// Simple invocation
myFunction(); // logs global object (window)
أثناء استدعاء طريقة قيمة this
هل الكائن يمتلك الطريقة:
function myFunction() {
console.log(this);
}const myContext = { value: 'A' };myFunction.call(myContext); // logs { value: 'A' }
myFunction.apply(myContext); // logs { value: 'A' }
أثناء الاحتجاج غير المباشر باستخدام myFunc.call(thisVal, arg1, ..., argN)
أو myFunc.apply(thisVal, [arg1, ..., argN])
قيمة ال this
يساوي الوسيطة الأولى:
function myFunction() {
console.log(this);
}const myContext = { value: 'A' };myFunction.call(myContext); // logs { value: 'A' }
myFunction.apply(myContext); // logs { value: 'A' }
أثناء استدعاء المُنشئ باستخدام new
كلمة رئيسية this
يساوي مثيل تم إنشاؤه حديثًا:
function MyFunction() {
console.log(this);
}new MyFunction(); // logs an instance of MyFunction
سلوك this
داخل دالة السهم يختلف اختلافًا كبيرًا عن الوظائف العادية this
سلوك. لا تحدد وظيفة السهم سياق التنفيذ الخاص بها.
بغض النظر عن كيفية أو مكان إعدامه ، this
القيمة داخل دالة السهم تساوي دائمًا this
قيمة من الوظيفة الخارجية. بمعنى آخر ، يتم حل وظيفة السهم this
معجميا.
في المثال التالي ، myMethod()
هي وظيفة خارجية لـ callback()
وظيفة السهم:
const myObject = {
myMethod(items) {
console.log(this); // logs myObject
const callback = () => {
console.log(this); // logs myObject
};
items.forEach(callback);
}
};myObject.myMethod([1, 2, 3]);
this
القيمة داخل وظيفة السهم callback()
يساوي this
من الوظيفة الخارجية myMethod()
.
this
حل معجميًا هو أحد الميزات الرائعة لوظائف السهم. عند استخدام عمليات الاسترجاعات داخل الطرق ، فأنت متأكد من أن وظيفة السهم لا تحدد وظيفتها this
: لا أكثر const self = this
أو callback.bind(this)
الحلول.
على عكس الوظيفة العادية ، فإن الاستدعاء غير المباشر لدالة السهم باستخدام myArrowFunc.call(thisVal)
أو myArrowFunc.apply(thisVal)
لا يغير قيمة this
: يتم دائمًا تحليل قيمة السياق معجمًا.
2. البناة
وظيفة منتظمة
كما رأينا في القسم السابق ، يمكن للوظيفة العادية إنشاء كائنات بسهولة.
على سبيل المثال ، ملف new Car()
وظيفة تخلق نماذج لسيارة:
function Car(color) {
this.color = color;
}const redCar = new Car('red');redCar instanceof Car; // => true
Car
هي وظيفة عادية. عند الاستدعاء مع new
كلمة رئيسية new Car('red')
- حالات جديدة من Car
تم إنشاء النوع.
دالة السهم
نتيجة this
تم حلها معجمًا هو أنه لا يمكن استخدام وظيفة السهم كمنشئ.
إذا حاولت استدعاء دالة سهم مسبوقة بـ new
الكلمة الأساسية ، JavaScrip تلقي خطأ:
const Car = (color) => {
this.color = color;
};const redCar = new Car('red');
// TypeError: Car is not a constructor
التذرع new Car('red')
، أين Car
هي وظيفة السهم ، رميات TypeError: Car is not a constructor
.
وظيفة منتظمة
داخل الجسم وظيفة منتظمة ، arguments
هو كائن خاص يشبه المصفوفة يحتوي على قائمة الوسيطات التي تم من خلالها استدعاء الوظيفة.
دعونا نستدعي myFunction()
تعمل مع وسيطتين:
function myFunction() {
console.log(arguments);
}myFunction('a', 'b'); // logs { 0: 'a', 1: 'b', length: 2 }
بداخل myFunction()
الجسم arguments
هو كائن يشبه المصفوفة يحتوي على وسيطات الاستدعاء: 'a'
و 'b'
.
دالة السهم
على الجانب الآخر ، لا arguments
يتم تعريف كلمة رئيسية خاصة داخل وظيفة السهم.
مرة أخرى (كما هو الحال مع this
القيمة) ، فإن arguments
تم حل الكائن معجمًا: تصل وظيفة السهم arguments
من الوظيفة الخارجية.
دعنا نحاول الوصول arguments
داخل وظيفة السهم:
function myRegularFunction() {
const myArrowFunction = () => {
console.log(arguments);
}
myArrowFunction('c', 'd');
}myRegularFunction('a', 'b'); // logs { 0: 'a', 1: 'b', length: 2 }
وظيفة السهم myArrowFunction()
مع الحجج 'c'
و 'd'
. ومع ذلك ، داخل جسده ، arguments
الكائن يساوي حجج myRegularFunction()
استدعاء: 'a'
و 'b'
.
إذا كنت ترغب في الوصول إلى الوسائط المباشرة لوظيفة السهم ، فيمكنك استخدام ميزة باقي المعلمات:
function myRegularFunction() {
const myArrowFunction = (...args) => {
console.log(args);
}
myArrowFunction('c', 'd');
}myRegularFunction('a', 'b'); // logs ['c', 'd']
...args
تجمع معلمة rest وسيطات التنفيذ لوظيفة السهم: ['c', 'd']
.
وظيفة منتظمة
return expression
تقوم العبارة بإرجاع النتيجة من دالة:
function myFunction() {
return 42;
}myFunction(); // => 42
إذا كان return
العبارة مفقودة ، أو لا يوجد تعبير بعد تعليمة الإرجاع ، فإن الدالة العادية ترجع ضمنيًا undefined
:
function myEmptyFunction() {
42;
}function myEmptyFunction2() {
42;
return;
}myEmptyFunction(); // => undefined
myEmptyFunction2(); // => undefined
دالة السهم
يمكنك إرجاع القيم من وظيفة السهم بنفس طريقة وظيفة عادية ، ولكن مع استثناء واحد مفيد.
إذا كانت وظيفة السهم تحتوي على تعبير واحد ، وقمت بحذف الأقواس المتعرجة للوظيفة ، فسيتم إرجاع التعبير ضمنيًا. هذه هي وظيفة الأسهم المضمنة.
const increment = (num) => num + 1;
increment(41); // => 42
ال increment()
يتكون السهم من تعبير واحد فقط: num + 1
. يتم إرجاع هذا التعبير ضمنيًا بواسطة دالة السهم دون استخدام return
كلمة رئيسية.
وظيفة منتظمة
الدوال المنتظمة هي الطريقة المعتادة لتعريف الطرق على الأصناف.
في الفصل التالي Hero
، طريقة logName()
يتم تعريفه باستخدام وظيفة عادية:
class Hero {
constructor(heroName) {
this.heroName = heroName;
}
logName() {
console.log(this.heroName);
}
}
const batman = new Hero('Batman');
عادةً ما تكون الوظائف العادية كطرق هي السبيل للذهاب.
قد تحتاج أحيانًا إلى توفير الطريقة باعتبارها رد اتصال ، على سبيل المثال لـ setTimeout()
أو مستمع الحدث. في مثل هذه الحالات ، قد تواجه صعوبات في الوصول this
القيمة.
على سبيل المثال ، دعنا نستخدم logName()
طريقة الاتصال ل setTimeout()
:
setTimeout(batman.logName, 1000);
// after 1 second logs "undefined"
بعد ثانية واحدة ، undefined
تم تسجيله في وحدة التحكم. setTimeout()
ينفذ استدعاءًا بسيطًا لـ logName
(أين this
هو الكائن العالمي). هذا عندما يتم فصل الطريقة عن الكائن.
دعونا نلتزم this
القيمة يدويًا إلى السياق الصحيح:
setTimeout(batman.logName.bind(batman), 1000);
// after 1 second logs "Batman"
batman.logName.bind(batman)
يرتب this
قيمة ل batman
نموذج. أنت الآن متأكد من أن الطريقة لا تفقد السياق.
ربط this
يتطلب يدويًا رمزًا معياريًا ، خاصةً إذا كان لديك الكثير من الطرق. هناك طريقة أفضل: يعمل السهم كحقل صف.
دالة السهم
بفضل اقتراح حقول الفصل (في هذه اللحظة في المرحلة 3) ، يمكنك استخدام وظيفة السهم كطرق داخل الفصول الدراسية.
الآن ، على عكس الوظائف العادية ، الطريقة المحددة باستخدام روابط الأسهم this
معجميًا إلى مثيل الفصل.
دعنا نستخدم وظيفة السهم كحقل:
class Hero {
constructor(heroName) {
this.heroName = heroName;
} logName = () => {
console.log(this.heroName);
}
}const batman = new Hero('Batman');
الآن يمكنك استخدام ملفات batman.logName
باعتباره رد اتصال بدون أي ربط يدوي لـ this
. قيمة ال this
داخل logName()
الطريقة هي دائمًا مثيل الفئة:
setTimeout(batman.logName, 1000);
// after 1 second logs "Batman"
يساعد فهم الاختلافات بين الوظائف العادية ووظائف الأسهم في اختيار الصيغة الصحيحة لاحتياجات معينة.
this
القيمة داخل دالة عادية ديناميكية وتعتمد على الاستدعاء. ولكن this
داخل دالة السهم مرتبطة معجمياً وتساوي this
من الوظيفة الخارجية.
arguments
الكائن داخل الوظائف العادية يحتوي على قائمة الوسائط. وظيفة السهم ، على العكس من ذلك ، لا تعرف arguments
(ولكن يمكنك الوصول بسهولة إلى وسيطات دالة السهم باستخدام معلمة rest ...args
).
إذا كانت وظيفة السهم تحتوي على تعبير واحد ، فسيتم إرجاع التعبير ضمنيًا ، حتى بدون استخدام return
كلمة رئيسية.
أخيرًا وليس آخرًا ، يمكنك تحديد الطرق باستخدام صيغة دالة السهم داخل الفئات. ربط طرق سهم الدهون this
قيمة مثيل الفئة.
على أي حال يتم استدعاء طريقة السهم السمين ، this
دائمًا ما يساوي مثيل الفئة ، وهو أمر مفيد عند استخدام العمليات كعمليات رد نداء.
لفهم جميع أنواع الوظائف في JavaScript ، أوصي بالتحقق من 6 طرق للإعلان عن وظائف JavaScript.
تريد الاتصال؟
درادين لديه شغف بالتعلم العميق وتصميم البرمجيات. قام بإنشاء العديد من تطبيقات الويب / الجوال المستندة إلى الذكاء الاصطناعي باستخدام خدمات مصغرة لمساعدة العملاء في حل مشكلات العالم الحقيقي. لا تتردد في القراءة عنه عبر محفظته أو ملفه الشخصي على جيثب.