طرق استدعاء الوظائف في JavaScript
في JavaScript، يمكن استدعاء الوظائف بطرق مختلفة، وهناك طريقتان شائعتان الاستخدام هما "call" و"apply". تسمح لك هذه الطرق بالتحكم في السياق (القيمة "هذه") التي يتم فيها تنفيذ الوظيفة. يعد فهم الفرق بين "استدعاء" و"تطبيق" أمرًا بالغ الأهمية لكتابة تعليمات برمجية JavaScript تتسم بالكفاءة والفعالية.
تستكشف هذه المقالة الفروق بين `Function.prototype.call()` و`Function.prototype.apply()` عند استدعاء دالة. سوف نقوم بفحص بناء الجملة وحالات الاستخدام والاختلافات المحتملة في الأداء. بحلول نهاية هذه المقالة، سيكون لديك فهم واضح للوقت الذي تستخدم فيه "call" بدلاً من "apply" والعكس صحيح.
يأمر | وصف |
---|---|
Function.prototype.call() | يستدعي دالة لها هذه القيمة والوسائط المقدمة بشكل فردي. |
Function.prototype.apply() | يستدعي دالة بقيمة معينة، ويتم توفير الوسائط كمصفوفة. |
this | يشير إلى الكائن الذي تم استدعاء الوظيفة منه، مما يسمح بتعيين السياق الديناميكي. |
console.log() | طباعة الرسائل أو المتغيرات إلى وحدة التحكم لأغراض التصحيح. |
res.writeHead() | يضبط رمز حالة HTTP ورؤوس الاستجابة في خادم Node.js. |
res.end() | ينهي عملية الاستجابة في خادم Node.js، مع الإشارة إلى أن جميع البيانات قد تم إرسالها. |
http.createServer() | إنشاء نسخة خادم HTTP في Node.js، والاستماع للطلبات الواردة. |
listen() | يبدأ تشغيل خادم HTTP، مما يسمح له بالاستماع على منفذ محدد. |
فهم استخدام الاتصال والتطبيق في JavaScript
توضح البرامج النصية المقدمة الاختلافات بين الاستخدام Function.prototype.call() و Function.prototype.apply() في جافا سكريبت. يتم استخدام كلتا الطريقتين لاستدعاء الوظائف ذات المحدد this سياق. في المثال الأول، call() يتم استخدام الطريقة لاستدعاء fullName طريقة على كائنات مختلفة (person1 و person2)، وتمرير خصائص كل كائن كوسيطات فردية. تسمح هذه الطريقة ببناء جملة موجزة عندما يكون عدد الوسائط معروفًا وثابتًا. المثال الثاني يوضح استخدام apply() الطريقة التي تشبه call() ولكنه يأخذ مجموعة من الحجج بدلاً من الحجج الفردية. تكون هذه المرونة مفيدة بشكل خاص عندما يكون عدد الوسائط متغيرًا أو يأتي من مصدر صفيف.
في مثال الواجهة الخلفية لـ Node.js، فإن call() يتم استخدام الطريقة داخل خادم HTTP تم إنشاؤه باستخدام http.createServer(). يسلط هذا المثال الضوء على كيفية this يمكن معالجة السياق في JavaScript من جانب الخادم للاستجابة ديناميكيًا لطلبات HTTP. يستجيب الخادم بتحية، موضحًا كيف call() الطريقة يمكن أن تغير سياق greet وظيفة. وأخيرًا، يوضح مثال الواجهة الأمامية والواجهة الخلفية المدمجتين كيفية تنفيذ كليهما call() و apply() يمكن استخدامها في وظيفة أكثر ديناميكية. باستخدام call() مع الحجج الفردية و apply() باستخدام مجموعة من الوسائط، يقوم البرنامج النصي بإنشاء تفاصيل المستخدم بشكل ديناميكي، مما يوضح التطبيقات العملية لهذه الأساليب في تطوير JavaScript من جانب العميل والخادم.
استخدام أساليب الاتصال والتطبيق في JavaScript لاستدعاء الوظيفة
جافا سكريبت سكريبت الواجهة الأمامية
// Example 1: Using Function.prototype.call()
const person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
const person1 = {
firstName: "John",
lastName: "Doe"
};
const person2 = {
firstName: "Jane",
lastName: "Smith"
};
// Call the fullName method on person1 and person2
console.log(person.fullName.call(person1)); // Output: John Doe
console.log(person.fullName.call(person2)); // Output: Jane Smith
تطبيق Function.prototype.apply() لتمرير الوسيطة المرنة
جافا سكريبت سكريبت الواجهة الأمامية
// Example 2: Using Function.prototype.apply()
const person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + ", " + city + ", " + country;
}
};
const person1 = {
firstName: "John",
lastName: "Doe"
};
const person2 = {
firstName: "Jane",
lastName: "Smith"
};
// Apply the fullName method with arguments on person1 and person2
console.log(person.fullName.apply(person1, ["New York", "USA"])); // Output: John Doe, New York, USA
console.log(person.fullName.apply(person2, ["London", "UK"])); // Output: Jane Smith, London, UK
مثال على الواجهة الخلفية لـ Node.js باستخدام الاتصال والتطبيق
JavaScript Backend Script مع Node.js
// Load the required modules
const http = require('http');
// Create a server object
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
// Example using call()
function greet() {
return 'Hello ' + this.name;
}
const user = { name: 'Alice' };
res.write(greet.call(user)); // Output: Hello Alice
res.end();
}).listen(3000);
console.log('Server running at http://localhost:3000/');
الجمع بين الاتصال والتطبيق مع وظيفة ديناميكية
جافا سكريبت سكريبت المكدس الكامل
// Define a function to display user details
function displayDetails(age, profession) {
return this.name + " is " + age + " years old and works as a " + profession + ".";
}
// User objects
const user1 = { name: 'Bob' };
const user2 = { name: 'Alice' };
// Use call to invoke displayDetails
console.log(displayDetails.call(user1, 30, 'Engineer')); // Output: Bob is 30 years old and works as a Engineer.
// Use apply to invoke displayDetails
console.log(displayDetails.apply(user2, [28, 'Doctor'])); // Output: Alice is 28 years old and works as a Doctor.
استكشاف معالجة السياق في جافا سكريبت
أبعد من الاستخدام الأساسي ل call() و apply()، يمكن دمج هذه الأساليب مع ميزات JavaScript الأخرى لإنشاء تعليمات برمجية أكثر تعقيدًا وقوة. على سبيل المثال، غالبا ما يتم استخدامها جنبا إلى جنب مع bind()، والتي تقوم بإرجاع دالة جديدة ذات دالة محددة this قيمة. على عكس call() و apply()، والتي تستدعي الوظيفة على الفور، bind() يمكن استخدامها لإنشاء دالة مرتبطة يمكن استدعاؤها لاحقًا بسياق ثابت. يعد هذا مفيدًا بشكل خاص في معالجة الأحداث، حيث قد ترغب في التأكد من احتفاظ الوظيفة بسياق كائن معين حتى عند تنفيذها في بيئات مختلفة.
تتضمن حالة الاستخدام المتقدمة الأخرى استعارة طرق من كائن لاستخدامها مع كائن آخر. ويمكن تحقيق ذلك باستخدام call() أو apply() لربط طريقة مؤقتًا بكائن مختلف. على سبيل المثال، أساليب المصفوفة مثل slice() أو push() يمكن استعارتها وتطبيقها على كائنات تشبه المصفوفة مثل كائن الوسائط في الوظائف. تتيح هذه التقنية قدرًا أكبر من المرونة وإمكانية إعادة استخدام التعليمات البرمجية، حيث تتيح مشاركة الأساليب عبر كائنات مختلفة دون تكرار.
أسئلة شائعة حول الاتصال والتطبيق في JavaScript
- ما هو الفرق الرئيسي بين call() و apply()؟
- الفرق الرئيسي هو ذلك call() يقبل قائمة من الحجج، في حين apply() يقبل مجموعة من الحجج.
- متى يجب أن تستخدم apply() زيادة call()؟
- يجب عليك استخدام apply() عندما يكون لديك مصفوفة من الوسائط أو تحتاج إلى تمرير عدد متغير من الوسائط إلى دالة.
- هل هناك فروق في الأداء بين call() و apply()؟
- بشكل عام، لا توجد فروق كبيرة في الأداء بين call() و apply(). أي اختلافات عادة ما تكون ضئيلة.
- يستطيع apply() يمكن استخدامها مع أساليب الرياضيات؟
- نعم، apply() يمكن استخدامها لتمرير مجموعة من الأرقام إلى أساليب الرياضيات مثل Math.max() أو Math.min().
- ما هو Function.prototype.bind()؟
- bind() ينشئ وظيفة جديدة، عند استدعائها، لها خاصيتها this تم تعيين الكلمة الأساسية على القيمة المقدمة، مع تسلسل محدد من الوسائط يسبق أي منها يتم تقديمه عند استدعاء الوظيفة الجديدة.
- كيف يمكن call() يمكن استخدامها لاستعارة الأساليب؟
- يمكنك استخدام call() لاقتراض أساليب من كائن واحد واستخدامها على كائن آخر، مما يسمح بإعادة استخدام الطريقة دون نسخ الوظيفة.
- هل من الممكن استخدامها call() أو apply() مع البنائين؟
- لا، لا يمكن استدعاء المُنشئين مباشرةً call() أو apply(). بدلا من ذلك، يمكنك استخدام Object.create() لأنماط الميراث.
- ما هي الكائنات الشبيهة بالمصفوفة، وكيف call() و apply() العمل معهم؟
- الكائنات المشابهة للصفيف هي كائنات لها خاصية طول وعناصر مفهرسة. call() و apply() يمكن استخدامها لمعالجة هذه الكائنات كما لو كانت صفائف.
تلخيص استخدام الاتصال والتطبيق في JavaScript
في جافا سكريبت، call() و apply() ضرورية للسيطرة على this السياق داخل الوظائف. call() يسمح بتمرير الوسائط الفردية، مما يجعله مناسبًا للوسائط المعروفة والثابتة. في المقابل، apply() يأخذ مجموعة من الوسائط، مما يوفر المرونة لقوائم الوسائط المتغيرة. تعمل كلتا الطريقتين على تحسين إمكانية إعادة استخدام التعليمات البرمجية واستدعاء الوظائف الديناميكية، سواء في تطوير الواجهة الأمامية أو بيئات Node.js. يعد فهم متى وكيف يتم استخدام هذه الأساليب بشكل فعال أمرًا بالغ الأهمية لكتابة تعليمات برمجية JavaScript نظيفة وفعالة.