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

Adnane Kadri

الأعضاء
  • المساهمات

    5129
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    51

كل منشورات العضو Adnane Kadri

  1. الغرض الأول من المولدات هو في كونها طريقة فعالة للتحكم في تنفيذ وتعليق شيفرة برمجية داخلها. بجانب انها لا تستهلك ذاكرة. لنقل اننا نحتاج أن نعالج منطقا معينا على أربع مستويات: function myFunc() { console.log('lvl 1 starts here') // lvl 1 code ============================ console.log('lvl 2 starts here') // lvl 2 code ============================ console.log('lvl 3 starts here') // lvl 3 code ============================ console.log('lvl 4 starts here') // lvl 4 code ============================ } استدعاء الوظيفة myFunc سيقوم بتنفيذ كامل منطق المستويات الأربع دفعة واحدة. الآن لو أردنا ان يمتلك كل مستوى خرجا معينا يمكن التعامل معه على نطاق خاص به، فإنه من الصعب تحقيقه عن طريق المنطق العادي لاحظ: function myFunc() { // تعليمات المستوى الأول ============================ return 'result after proccessed at level 1'; // =========== سيتم تجاهل كل التالي // تعليمات المستوى الثاني ============================ return 'result after proccessed at level 2'; // تعليمات المستوى الثالث ============================ return 'result after proccessed at level 3'; // تعليمات المستوى الرابع ============================ return 'result after proccessed at level 4'; } لأننا لن نصل من الأساس الى اي من المستويات الأخرى لأن return ستقوم بإيقاف تنفيذ التعليمات البرمجية عند اول مستوى وفقط. الحل هنا، هو في استعمال المولدات Generators، فبعد ان نعالج المعطيات على المستوى الاول يمكننا الاستفادة من عائد (نسميه نتيجة المولد Generator result) يميزه. وبدون الحاجة الى اعادة استدعاء فإنه سيمكنناعن طريق طلب المستوى التالي متى احتجنا المرور الى المستوى الثاني وهكذا. لاحظ المثال: function * myFunc() { // تعليمات المستوى الأول ============================ yield 'result after proccessed at level 1'; // =========== لن يتم تجاهل كل التالي // تعليمات المستوى الثاني ============================ yield 'result after proccessed at level 2'; // تعليمات المستوى الثالث ============================ yield 'result after proccessed at level 3'; // تعليمات المستوى الرابع ============================ yield 'result after proccessed at level 4'; } لاحظ أنه يتم تمييز دوال المولدات في جافاسكربت عن طريق النجمة وعائد المولد عن طريق الكلمة yield. لاحظ التطبيق العملي لها: var myGen = myFunc(); console.log(myGen.next().value) console.log(myGen.next().value) console.log(myGen.next().value) console.log(myGen.next().value) النتيجة: "result after proccessed at level 1" "result after proccessed at level 2" "result after proccessed at level 3" "result after proccessed at level 4" فالمولد هنا يحتفظ بالمستوى الذي هو عليه كل مرة نطلب فيها مستوى جديدا. الشيء الآخر المميز في المولدات هو في كونها كائنات قابلة للتكرار iterable فعلى سبيل المثال يمكنك عن طريقها انشاء تكرار لا متناهي دون ان يتوقف مفسر الشيفرة البرمجية عن العمل: function * infLoop() { let i = 0; while(true) yield i; } var inf = infLoop(); console.log(inf.next().value) console.log(inf.next().value) الآن لو احتجت استدعاء infLoop مليون مرة فستحافظ كل مرة على نطاقها الخاص الذي تستدعى ضمنه مرة واحدة.
  2. لم أواجه المشكلة التي تصادفينها، استطيع تكوين وتعطيل بروتوكول عميل واعداده لاستخدام TCP/IP بشكل عادي. يحتمل ان يكون ذلك بسبب خطأ في اعداد وتكوين SQL Server لديك. أقترح كحل للمشكلة اعادة تثبيته من جديد تماما، تأكدي فقط من تثبيت النسخة الافتراضية basic أثناء تثبيته. قد لا يتم التثبيت بشكل صحيح في حالة انقطاع الانترنت ولذلك يجب التأكد من البقاء على اتصال الى حد تحميل ملفات الاعداد وانطلاق التثبيت. في حالة تمام التثبيت يمكنك اتباع الخطوات التالية لذات الغرض السابق: فيما يلي رابط التحميل الرسمي لنسخة المطور نسخة 2019.
  3. مرحبا أحمد، يمكنك التواصل مع مركز مساعدة أكاديمية حسوب بهذا الخصوص.
  4. لتكوين عميل لاستخدام TCP/IP اتبعي الخطوات التالية: قومي بفتح SQL Server Configuration Manager. من قائمة SQL Server Native Client Configuration اضغطي بالزر الأيمن على Client Protocols ثم على Properties. من قسم Enabled protocols استعملي الاسهم لتغيير ترتيب البروتوكولات حيث ان البروتوكول الاول في الترتيب سيعتمد كافتراضي.
  5. ما هي المشكلة تحديدا؟ ان كانت تظهر رسالة خطأ ما، هل يمكنك ارفاقها ايضا؟ السؤال يفتقر الى الشرح أكثر
  6. بجانب ما اقترحه المدربون يمكنك استعمال الواجهة البرمجية لـ ReflectionClass في PHP عن طريق التابع implementsInterface: <?php interface OtherInterface { /**/ } interface IUser { /**/ } class MyClass implements IUser { /**/ } $class = new ReflectionClass('MyClass'); echo $class->implementsInterface('IUser'); // true echo $class->implementsInterface('OtherInterface'); // false مثلما يمكنك عمل نفس الشيء عن طريق الوظيفة is_subclass_of في حالة الحاجة الى التحقق من ما ان كان كائن من ما عن صنف ما يطبق واجهة: <?php interface OtherInterface { /**/ } interface IUser { /**/ } class MyClass implements IUser { /**/ } $class = new MyClass(); echo is_subclass_of($class, 'IUser'); // true echo is_subclass_of($class ,'OtherInterface'); // false للاستزادة: دوال التعامل مع الكائنات والأصناف في PHP
  7. ملفات العرض داخل مجلد view تحوي قوالب وهياكل مكتوبة بـ HTML ملفات اللغات داخل مجلد languages تحوي نصوص الترويسات والنصوص الوصفية
  8. أظنك تستخدم نسخة قديمة من اوبن كارت (تفاصيل الاصدار الرئيسي )، فهذا هو محتوى الصفحة الرئيسية index.php فيها يمكنك استعراضها من هنا. يستعمل opencart نمط تصميم MVCL اختصارا عن Model , View , Controller , Language ولذلك ستحتاج على الاقل معرفة بهذا النمط من التصميم للتعديل على مكونات opencart. لاحظ ضمن مجلد catalog مثلا أنه يوجد أربع مجلدات او تفرعات (او اهتمامات) كل منها يمثل مكونا مهما في هذا النمط: view: تمثل كامل ملفات العرض، من قوالب وهياكل يتم عرضها في الصفحة. language: تمثل كامل ملفات اللغات، في العادة تحوي مصفوفات ترابطية بمفتاح وقيمة يمكنك فيها ايجاد النصوص الوصفية ونصوص الترويسات وتعديلها بما يلائمك. model: وهي ملفات نماذج البيانات وهياكلها. controller : يحوي كامل ملفات المتحكمات وهي الوحدات التي تستقبل الطلبات والبيانات من ملفات العرض وتعالجها قبل تطبيقها على ملفات النماذج. سيمكنك ايجاد نفس الشيء في مجلد admin أيضا. هذا التنظيم هو المتبع في اطر عمل وانظمة ادارة بحجم OpenCart . ولهذا لن تجد كامل شيفرات الـ PHP و اللغات والـ HTML في صفحة واحدة. لا يقترح التعديل على هاته المكونات مباشرة، لأن هذا يتطلب خبرة بهذا النمط من التصميم، بجانب التعرف على OpenCart وفهم طريقة عمله. يمكنك الاستفادة من شروحات openCart في اكاديمية حسوب.
  9. بالطبع، يمكنك الوصول الى قسم توثيق الواجهة Document من هنا. سيمكنك ايجاد كل ما يمثل شجرة الوثيقة فيه.
  10. ماذا عن قسم جافاسكربت في موسوعة ويكي حسوب؟ تهدف موسوعة حسوب لتوفير توثيق عربي كامل وعالي الجودة، مدعم بالأمثلة لمختلف لغات البرمجة وتقنيات تطوير الويب والجوال. محتوى موسوعة حسوب هو محتوى مرجعي، أي هو أقرب للقاموس تبحث فيه عمّا تحتاج له عند الحاجة ان كنت تواجه أي مشاكل برمجية او تساؤلات يمكنك الاستعانة بموقع أكاديمية حسوب.
  11. بالنسبة للتحقق من عنوان البريد الالكتروني فهو صحيح نعم، سيتم التحقق من ما ان كان العنوان المرفق عنوانا صالحا او لا عن طريق الوظيفة filter_var والـ flag المرفق كـ FILTER_VALIDATE_EMAIL . يشمل هذا التحقق من انه لا يحوي مساحات بيضاء او تنقيطا فالاسم وغيرها ولا يعني هذا احتواءه على رمز @ فقط. أظنك ستحتاجين تغيير رسالة الفشل من التحقق التي تظهر الى أخرى أكثر دلالية من مثل: if(!filter_var($email,FILTER_VALIDATE_EMAIL)){ echo "enter a valid email address"; } أما عن التعبير النمطي الذي تستخدمينه في التحقق من كلمة المرور الخاصة بك، فهو غير صالح. لاحظي رسالة التنبيه التي تظهر في حالة تجربته: Warning: preg_match(): Compilation failed: quantifier does not follow a repeatable item at offset 5 in /home/user/scripts/code.php on line 4 قمت ببعض التعديلات عليه ليكون بالشكل التالي: <?php $regx = '~^(?=.*?[A-Z])(?=.*?[a-z]).{7,}$~'; echo preg_match($regx ,'ValidExample'); // true echo preg_match($regx ,'not_valid'); // false echo preg_match($regx ,'Short'); // false
  12. لا تبدوا فكرة وراثة أكثر من صنف منطقية بالنسبة للبرمجة كائنية التوجه. هل يمكن معرفة الغرض الأول من ذلك؟ ربما ستفضل استعمال السمات لاستخدام توابع متعددة من سمات متعددة. لاحظ المثال: trait A { public function method_from_a($s) { echo $s; } } trait B { public function method_from_b($s) { echo $s; } } trait C { public function method_from_c($s) { echo $s; } } class D { use A,B,C; } $d = new D; $d->method_from_a('from a'); $d->method_from_b('from b'); $d->method_from_c('from c'); بجانب ان الأمر غير مقيد، سيمكنك استعمال مالانهاية من السمات. ان كان الأمر مقيد بثلاث أصناف بالضبط فسيمكنك كفكرة تزييف هاته العملية عن طريق وراثة صنف A من صنف B ثم الاستعانة بالتابع السحري call_ لإستدعاء تابع ما ضمن صنف ثالث C. يكون ذلك بشكل مشابه: class B { public function called_from_b($str) { echo $str; } } class C { public function called_from_c($str) { echo $str; } } class A extends B { private $c; public function __construct() { $this->c = new C; } public function __call($method, $args) { $this->c->$method($args[0]); } } $a = new A; $a->called_from_b("abc"); $a->called_from_c("def"); حيث أن: A يرث B A يمتلك خاصية c هي كائن عن النموذج C في حالة استدعاء تابع غير موجود لا في B ولا في A سيتم الاستعانة بالتابع السحري call_ لارساله من C
  13. بجانب الطرق التي اقترحها المدرب سامح، يمكنك الاستفادة من طريقة النسخ المنظم أو المهيكل structured cloning عن طريق الوظيفة الجديدة structuredClone الموجودة في جافاسكربت كالتالي: var newObj = structuredClone(myObj); مثال: /*الكائن الأصلي*/ var myObj = {a: 1, b: 2, c: 3} /*نسخة عن الكائن*/ var newObj = structuredClone(myObj) /*استعراض النسخة أول الأمر*/ console.log(newObj) /*تغيير خاصية بالكائن الاصلي واعادة استعراض الكائنين*/ setTimeout(() => { myObj.a = 5 console.log(myObj , newObj) } ,2000) مثال عملي.
  14. يمكنك وضع قواعد تنسيقات CSS ضمن العنصر <style> في مستند HTML كالتالي: <style type="text/css"> p { color: red; } </style> أو عن طريق وضع التنسيقات ضمن ملف بلاحقة css، ثم تضمينه عبر العنصر <link>: <link href="style.css" rel="stylesheet" type="text/css"> نفس الأمر بالنسبة للجافاسكربت، يمكنك تضمين شيفرة JavaScript في أي مكان داخل المستند داخل عنصر <script> كما يلي: <script> // شيفرات JavaScript </script> أو عن طريق وضع هاته الشيفرات في ملف بلاحقة جافاسكربت js (وليكن اسمه script.js) ليمكن تضمينه باستخدام العنصر <script> مع الاشارة لمساره في قيمة الخاصية src كما يلي: <script src="script.js"></script>
  15. دورة تطوير التطبيقات باستخدام لغة جافاسكربت في اكاديمية حسوب هي تشكيلة ذات 55 ساعة من أساسيات اللغة، تطبيقاتها العملية وتفرعاتها المختلفة في مختلف بيئات العمل. حيث تحتوي كلا من المسارات التالية: أساسيات لغة جافاسكربت أساسيات ReactJS أساسيات NodeJS تطوير تطبيق جوال بإستخدام React Native تطوير تطبيق دردشة يشبه WhatsApp تطوير تطبيق سطح مكتب باستخدام ElectronJS تطوير تطبيق جوال للتواصل الاجتماعي باستخدام Ionic تطبيق حجز مناسبات باستخدام GraphQL وبالتالي فإنك ستصبح قادرا على التعامل مع جافاسكربت في كل بيئة، انطلاقا من جهة الخادم بـ Node و Express و العميل بـ ReactJS و Vanilla Javascript والهاتف النقال عن طريق ReactNative و Ionic و سطح المكتب عن طريق ElectronJS بجانب التعامل مع قواعد البيانات عن طريق كل من GraphQL و MongoDB و NoSql. ولو تلاحظ فإن الدورة مشبعة بمسارات العمل التطبيقية، وهو شيء يميز الدورة أكثر. بعد اتمامك للدورة ستتخرج كمطور جافاسكربت. يمكنك التعرف أكثر عن الدورة هنا.
  16. بالطبع فإنه يوجد فرق، عملية الـنمذجة ترجمة عن prototyping في هي نمط تصميم يخص إنشاء الكائنات Objects يندرج تحت الفئة creational design patterns أو انماط التصميم الإنشائية. وفي جافاسكربت وهو ببساطة أشبه بالاشارة الى النموذج الأولي للكائن وهو ما كالتالي: function User () { }; User.prototype.save = function () { //do something }; فهاهنا نحن نقوم بتهيئة طريقة او تابع او وظيفة للصنف User يستعمله هو نفسه كامل الكائنات المنشئة عن طريق User وليكن الكائنين Ali و Ossama. وذلك لأن كل كائن مرتبط بكائن النموذج الأولي (لنتخيله كالقالب الأولي). في حين ان استعمال this سيشير الى الكائن المنشَئ وليس للصنف، بمعنى انه سيشير الى Ali وحده والى Ossama وحده. فكل كائن منهما سيمتلك نسخته الخاصة من save. تعتبر الطريقة الأولى أو النمذجة أسرع نسبيا وأقل استعمالا للذاكرة (لأن التابع سيكون متوفرا عند كل النسخ عن الصنف عند استعمال this في حين انه سيكون متوفرا في النموذج الاولي فقط في حالة استعمال prototype) أما الطريقة الثانية فهي تخدم مفهوم التغليف Encapsulation أكثر فالتوابع المعرفة داخل الكائن بالاشارة بـ this يمكنها التعامل مع متغيرات الكائن الداخلية الخاصة. في الحقيقة لا يوجد هذان النمطين فقط في جافاسكربت فيما يخص الكائنات، يوجد أنماط عديدة أخرى يتعلق بعضها بتهئية الكائنات وإنشاءها، بأشكالها وكيفية عملها، بسلوكها وكيفية تواصلها وغيرها.
  17. لما قد تستخدمين التعابير النمطية لذلك؟ يمكن عن طريق عبارة شرطية بسيطة التحقق من ذلك. لاحظي: <?php $num = 18; $isGreaterThan18 = $num >= 18 ? true : false; echo $isGreaterThan18; لاحظي استعمال المعامل الثلاثي Ternary operator. ان كان لا بد من استخدام التعابير النمطية يمكنك الاستفادة من هذا التعبير: ^0?1[89]|0?[2-9][0-9]$ الذي يشمل الاعداد من 18 الى 99. شرح التعبير: ^ بداية التعبير 0؟ قبول ان تكون بداية السلسلة النصية 0 على نحو 068 او 018 1[89] تقبل ان يكون المحرف الاول 1 والثاني 8 او 9 اي قبول 18 و 19 و أيضا 018 و 019 | أو [2-9][0-9] ان يكون المحرف الاول ما بين 2 و 9 والثاني ما بين 0 و 9 على نحو 24 و 20 و 45 وغيرها $ نهاية التعبير فيما يلي استعماله بشكل عملي: $regex = "~^(^0?1[89]|0?[2-9][0-9]$)$~"; echo preg_match($regex ,80); // true echo preg_match($regex ,16); // false
  18. يمكنك استعمال الحدث submit عن طريق الموجه wire:submit لخدمة هذا الغرض، لنقم أولا بإنشاء مكون livewire يمثل النموذج الخاص بنا عن طريق: php artisan make:livewire mySimpleForm وليحمل ملف العرض المرافق لهذا المكون الهيكلة التالية: <div> <h2> {{ $num }} </h2> <from wire:submit.prevent="handleData"> <input type="number" name="number1" wire:model="number1"/> <input type="number" name="number2" wire:model="number2"/> <button type="submit"> حفظ </button> </form> </div> لاحظ استقبال المتغير num الذي سيتم تكوينه عن طريق صنف المكون MySimpleForm.php لاحظ ايضا استعمال الحدث submit.prevent لمنع تقديم النموذج بشكل افتراضي (لمنع تحديث الصفحة عند تقديمه) لاحظ أيضا استعمال الحدث model للاستماع لكل من قيم number1 و number2 لاحظ استعمال التابع handleData الذي يمثل تابع صنف المكون MySimpleForm الذي سيقوم بالتعامل مع البيانات التي نرسلها. يكون ملف صنف المكون MySimpleForm كالتالي: <?php namespace App\Http\Livewire; use Livewire\Component; class MySimpleForm extends Component{ public $number1; public $number2; public $num = 0; public funciotn handleData() { $this->num = $this->number1 + $this->number2; } public function render() { return view('livewire.my-simple-form'); } } الذي سيحصل هنا هو: عندما نملئ النموذج ونقدمه سيتم استهداف التابع handleData للصنف MySimpleForm عن طريق livewire ويتم تبديل قيمة num. (ستلاحظ تبديل قيمة num في ملف العرض كإثبات على تقديم النموذج وذلك دون الحاجة الى اعادة تحديث الصفحة). بالطبع فإنه يمكنك التعامل مع هاته البيانات وفق أي طريقة تريدها، أو تضمين هذا المكون بأي مكان أو صفحة أخرى.
  19. لا أظن أنه يوجد ميزات مبنية في جافاسكربت تدعم تطبيق الواجهات وتعريفها، ولكن يمكن تطبيق مفهوم قريب منه عن طريق تعريف توابع الواجهة اللازمة محقون فيها رسائل او تنبيهات خطأ في حالة استدعاءها دون اعادة الكتابة عليها. يفرض هذا وراثة الأصناف extending وليس تطبيق الواجهات implementing مثلما هو شائع مع الواجهات. لاحظ المثال: class MyInterface { // تابع اجباري example(a, b) { this._WARNING('sum(a, b)'); // يتم رمي هذا الخطأ في حالة عدم اعادة تعريفه } // مولد خطأ مخصص _WARNING(fName='unknown method') { console.warn( 'WARNING! Function "' +fName+ '" is not overridden in '+ this.constructor.name); } } class MyCorrectUsedClass extends MyInterface { /** اعادة تعريف التابع */ example(a, b) { return a+b; } } class MyIncorrectUsedClass extends MyInterface { // عدم اعادة التعريف } let correct = new MyCorrectUsedClass(); let incorrect = new MyIncorrectUsedClass(); console.log('correct.sum(1, 2) =', correct.example(1, 2)); console.log('incorrect.sum(1, 2) =', incorrect.example(1, 2)); سيعطي هذا رسالة خطأ مخصصة تخبرنا أننا يجب ان نعيد تعريف التابع example قبل استعماله، وهو بشكل ما أشبه بتطبيق واجهات. مثال عن خرج النتيجتين: "correct.sum(1, 2) =", 3 "WARNING! Function \&quot;sum(a, b)\&quot; is not overridden in MyIncorrectUsedClass" "incorrect.sum(1, 2) =", undefined
  20. كشخص من خلفية غير تقنية مبتدئ تماما في المجال أنصح بدورة علوم الحاسوب، فهي ما سيمهد لأي مبتدئ من أي خلفية الطريق لدخول هذا العالم من بابه الواسع، وذلك إبتداءا من أبسط المفاهيم البرمجية إلى المفاهيم المتقدمة. الدورة هي عبارة عن مساق تدريبي كامل يبدأ من الصفر تمامًا إلى مرحلة متقدمة من التعامل مع مختلف التقنيات. للدورة ثمان مسارات مختلفة: مدخل إلى علوم الحاسوب أساسيات البرمجة أنظمة التشغيل ولينكس قواعد البيانات إلى عالم الويب البرمجة الكائنية الخوارزميات وبنى المعطيات أنماط التصميم سيساعدك هذا في اختيار مسارك التعلمي وحسمك لموضوع التخصص مستقبلا، سواءا ان كنت ستختار تطوير واجهات المستخدم، تطبيقات الهاتف النقال أو تطبيقات الويب أو سطح المكتب. أما ان كنت تأتي من خلفية تقنية، وتعي كامل أساسيات البرمجة وعلوم الحاسب فيفترض أنك تعرف مجالات التخصص وبالتالي فلك أن تختار احد الدورات: دورة تطوير واجهات المستخدم. دورة دورة تطوير التطبيقات باستخدام بايثون دورة تطوير التطبيقات باستخدام جافاسكربت دورة تطوير التطبيقات باستخدام PHP دورة تطوير التطبيقات باستخدام Ruby
  21. متى ما رغبت في جعل كل عملية داخل الوظيفة وظيفة جزئية مستقلة ذات نطاق خاص. بحيث تكون قابلة للتطوير، التعديل أو التوسع بشكل مستقل عن أي وظيفة جزئية أخرى داخل نفس المهمة. لاحظ المثال المرفق آخر الإجابة:
  22. تقنية currying في جافاسكربت هي أحد تقنيات البرمجة الوظيفية المتقدمة، والتي تجعل الدوال من على الشكل: function(a , b , c) قابلة للإستدعاء كـ: function(a)(b)(c) ويقتضي هذا اعادة دالة من داخل دالة للحصول على هذا النوع من التسلسل. فالدالة الأولى تقوم بإستقبال المعامل a وتعالجه ثم تعيد الوظيفة التي تأخذ المعامل الثاني b وهكذا. أي أنه يعني ببساطة تحويل الوظائف والدوال ذات الوسيطات (المعاملات) المتعددة وتحليلها في سلسلة من الوظائف ذات معامل واحد. لاحظ المثال: الدالة التالية تقوم بحساب مساحة مكعب نعطي أبعاده. function calculateVolume(length, breadth, height) { return length * breadth * height; } console.log(calculateVolume(4, 5, 6)); يمكن كتابة هاته الدالة بتقنية currying كـ: function calculateVolume(length) { return function (breadth) { return function (height) { return length * breadth * height; } } } console.log(calculateVolume(4)(5)(6)); أو: function calculateVolume(length) { return (breadth) => { return (height) => { return length * breadth * height; } } } console.log(calculateVolume(4)(5)(6)); السبب في خلق النوع من التسلسل هو الحاجة الى الحصول على دوال جزئية بسهولة. فأنت لست مرغما على تمرير كامل المعاملات مرة واحدة بل سيكفي تمرير كل معامل عند توفره. مثال: نمرر المعامل length في مكان ونحفظ خرج الوظيفة ثم بعد توفر المعامل breadth نمرره ونحفظ الخرج ثم ان توفر المعامل height نمرره ثم نطبع الخرج. أي انه هاته الوظيفة ستعيد: اما دالة جزئية جديدة في حالة لم يكن عدد الوسطاء (المعاملات) كافيا أو تعيد النتيجة النهائية ان كان عدد الوسطاء كافيا. أظن الذي يجعل هاته التقنية مثيرة للإهتمام هو في أنها تساعد في جعل كل وظيفة جزئية ذات نطاق خاص scope يمكنك من فعل ما تريد دون القلق بشأن المتغيرات الخارجية. وهو ما يساهم حتما في فصل المهام. مثال واقعي: // دالة حساب السعر النهائي انطلاقا من سعر المنتج مضافا اليه العمولة ومطبقا عليه الخصم function getFinalPrice(actualPrice, charges, discountRate) { var finalPrice; finalPrice = actualPrice + charges - (actualPrice * discountRate/100); return finalPrice; } function getFinalPrice(actualPrice) { return (charges) => { return (discountRate) => { return actualPrice + charges - (actualPrice * discountRate/100); } } } console.log(getFinalPrice(100)(25)(12)) فان استوفت الوظيفة كامل معاملاتها، ستعيد لك خرجا يعبر عن السعر النهائي. وإن لم تستوف فإنها ستعيد دالة جزئية قابلة للإستدعاء مجددا callable. ولن يهم الخرج النهائي ولا المتغيرات الخارجية ان كنت ستقوم مستقبلا بتقليل كامل نسب الخصومات بغض النظر عنها بـ 1% أو ان كنت ستضيف 10$ على كل عملية شراء مهما كانت عمولتها الأصلية أو أي كان. فيما يلي مقالة مفصلة حول الموضوع: تقنية Currying في جافاسكربت
  23. بجانب الطريقة التي اقترحها المدرب حيدر يمكنك التحقق من ما ان كان احد المحارف على الاقل مكتوبا كـ capital، وفي ذلك نحتاج التحقق من كل عنصر من المصفوفة المشكلة من محارف السلسلة النصية المستهدفة. نستعمل في هذا الدالة ctype_upper التي تتأكد من ما ان كانت السلسة الممررة اليها مكتوبة بشكل capital او لا <?php $str = 'thats a string, and here is a capital letter : H'; function containsCapital($str) { // انشاء مصفوفة من محارف السلسلة النصية // والتكرار حول عناصر هاته المصفوفة foreach(str_split($str) as $item){ // للتحقق من ما ان كان هذا المحرف كبيرا ctype_upper استعمال الدالة if(ctype_upper($item)){ return true; } } // عدى ذلك، نعيد قيمة بوليانية خاطئة return false; } echo containsCapital($str); // true توثيق الدالة str_split
×
×
  • أضف...