English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
يبدو أن القليل من الناس يتحدثون عن المرجع والنسخ في جافا سكريبت، ولكن يمكن أن يساعد فهم هذه المفاهيم في فهم الكثير من الأشياء
سأبدأ بشرح الأشياء الأساسية، لنرى ماذا يتم تمريره من أنواع البيانات المختلفة في جافا سكريبت
مرجع: الأجسام، المجموعات، الدوال
نسخ: الأرقام، الحقائق
ستوضح النصوص بشكل منفرد، لأنها لها طبيعة خاصة، لا يمكن تحديد ما إذا كان يتم تمرير المرجع أم نسخ القيمة ( لأن قيمة النصوص لا يمكن تغييرها، لذا لا يبدو أن هذا السؤال له معنى) ولكن عند مقارنة المستخدمين، فإنه يبدو أن هذا ينتمي إلى مقارنة القيمة (سأشرح هذا الموضوع لاحقًا)
سأشرح لك كيف يتم التعبير عن ذلك عند الاستخدام
أكثر الاستخدامات شيوعًا هو التخصيص
var a = 1; var b = a; //تم تمرير نسخة من قيمة a b ++; alert(a); //"1" تعديلات b لا تؤثر على a /****************************************/ var a = [1]; var b = a; //تم تمرير مرجع a b[0] ++; alert(a); //"2" تعديلات b تؤثر على a ولكن بالطبع b = [2]; تعديلات هذا لا تؤثر على a.
معلمات الدالة
تمرير القيمة: يتم تمرير نسخة من القيمة إلى الدالة، لا يمكن رؤية التعديلات في الخارج
var a = 1; var b = 2; function change(a,b) { var c = a; a = b; //استبدال النسخ الجديد b = c; alert(a); //"2" alert(b); //"1" }; change(a,b); alert(a); //"1" alert(b); //"2"
تمرير المرجع:يتم تمرير مرجع قيمة إلى الدالة، يمكن رؤية تعديل الخصائص في الدالة من الخارج، ولكن يمكن تغطية المرجع الجديد في الخارج لا يمكن رؤيته، مثل
var a = [1, 2, 3]; var b = [5, 6]; function change(a,b) { a[0] = 4; //تعديل الخصائص الخارجية مرئي var c = a; a = b; //استبدال النسخ الجديد b = c; alert(a); //"5,6" alert(b); //"4,2,3" }; change(a,b); alert(a); //"4,2,3" alert(b); //"5,6"
من النتائج يمكن رؤية أن a و b لم يتم تبديلها... لأن النسخ الجديد يغطي الظاهر الخارجي هذا طبيعي لأن الدالة حصلت فقط على الإشارة وليس لديها الحق في تغيير الإشارة
هذا ليس كما هو الحال فيما يلي
var a = [1, 2, 3]; var b = [5, 6]; function change() { var c = a; a[0] = 4; a = b; b = c; }; change(); alert(a); //"5,6" alert(b); //"4,2,3"
تم تحقيق التبديل بنجاح
يجب ذكر مجال التبويب في الجافا سكربت مرة أخرى، هذا يجب أن يكون خطأً في بعض اللغات، لأن الجافا سكربت لا يحتوي على مجال التبويب، لذا عندما لا يجد a،b في change، سيبحث تلقائيًا في المستوى العالي، لذا فإن a،b في هذا المكان هي إشارات متغيرات المستوى العالمي
والمفردات a،b في الدالة change هي متغيرات الدالة، يتم نقل إشارات a،b عند استدعاء الدالة وتسليمها إلى هذه المتغيرات، ولكن لا يمكن تغيير a،b في المستوى العالمي، لذا يكفي تغيير الاسم لفهم ذلك بشكل أفضل
سأذكر هذا بسرعة... بعض الأمور منحرفة عن الموضوع
العودة إلى الإشارة والنسخ في الأمور التي يجب مراعاتها في عمليات التبديل
مقارنة التبديل هي مقارنة بالقيم، ومقارنة الإشارة هي مقارنة بالإشارات، حتى لو كانت القيم متطابقة، فإن الإشارات المختلفة ليست متطابقة
1 == 1; //صحيح 1 === 1; //صحيح [0] == [0]; //خطأ [0][0] == [0][0]; //صحيح [0][0] === [0][0]; //صحيح [0].toString() == [0].toString(); //صحيح
في التبويب...
التبويب هو أكثر الأشياء تعقيدًا في الجافا سكربت، سؤال شائع في مقابلاتنا في القسم، لا يزال يتم استخدامه بشكل متكرر
في هذا الجزء، لن أتحدث عن أشياء التبويب، بل سأتحدث فقط عن أجزاء التبديل والإشارة، عندما أكون واثقًا من أنني يمكنني توضيح ذلك بشرح واضح وبعبارات بسيطة وبأمثلة حية، سأقوم بشرح ذلك الشخص الذي لا يمكن تجاهله في الجافا سكربت
في التبويب، يستخدم الدالة الداخلية إشارات الاستدلال على المتغيرات المحلية للدالة الخارجية بدلاً من النسخ
في الواقع، هذا جزء مهم جدًا من فهم التبويب، يمكن استخدامه لشرح ظاهرة تبويب كلاسيكية، مثال يستخدم في كثير من الأماكن لشرح التبويب
/*إنشاء دالة، تعيين وحدة معالجة الحدث للعناصر في المجموعة، عندما يتم ضرب عنصر، يتم عرض رقم العنصر في alert*/]} var add_handlers = function (nodes) { var i; for (i = 0, l = nodes.length; i < l; i ++) { nodes[i].onclick = function (e) { alert(i); // بالطبع، الناتج هنا سيكون دائمًا عدد العناصر في كل مرة.... }; }; };
لماذا يكون الناتج دائمًا عدد العناصر وليس الرقم المتوقع؟ هذا يمكن تفسيره بسهولة باستخدام النسخ والارتباط
بما أن الدوال الداخلية تستخدم طرق الارتباط عند استخدام المتغيرات الخارجية بدلاً من النسخ، أعني أنني أمر كل عنصر بتعيين وحدة تحكم الحدث onclick عندما أمر بتعيين وحدة تحكم الحدث alert، عند تفعيل حدث onclick للعنصر، قيمة i قد أصبحت عدد العناصر....
var add_handlers = function (nodes) { var i; for (i = 0, l = nodes.length; i < l; i ++) { nodes[i].onclick = function (i) { return function(){ alert(i); }; }(i); }; };
السبب في أن هذا التعديل صحيح هو أن ما يتم إيصاله هو نسخة من قيمة i، وهي نفسها مثل الدالة العادية، لا تدع البندول يربكك، عودوا إلى الجوهر لتفهموا، الجوهر هو ما تم ذكره أعلاه حول نقل الارتباط
لنبدأ بالإشارة إلى أن لا تدع الاسم الغريب للبندول يخيفك، في الواقع هو نفس المبدأ الذي نستخدمه في الدوال العادية، دعنا نتجنب تلك الافتراضات مثل "حياة أطول" و "حماية المتغيرات الخاصة" وغيرها من خصائص البندول المزعومة، وإذا نظرنا إليها كدوال عادية (أو يمكننا النظر إلى الدوال العادية كبندولات خاصة)، فإنها سهلة الفهم
المهم هو أن نغادر كل التفاخر ونعد إلى الجوهر.... هل غابت عن الموضوع مرة أخرى....
هذا المقال السريع حول الاستدلال والنسخ في JavaScript (التنقل والاستنساخ) هو كل ما سأشاركه معكم، آمل أن يكون هذا مرجعًا لكم، وأتمنى أن تدعموا دائمًا دروس呐喊.