لماذا يكسر JavaScript العقل ولكن لا يجب أن يكسر المهنة
\n\nJavaScript هي في نفس الوقت أكثر لغات البرمجة ودًا وأكثرها غدرًا. من ناحية، تكتب console.log('Hello') - وتظهر النتيجة فورًا في المتصفح. ومن ناحية أخرى، قد يعطي نفس الكود فجأة undefined أو NaN أو ما هو أسوأ، وستقضي ساعة في البحث عن خطأ يختبئ في سطر واحد.
في pythonlib.ru، نعرف مدى أهمية التعلم من أخطاء الآخرين. في هذه المقالة، سنحلل 5 أخطاء نموذجية للمبتدئين في JavaScript تحول الكود إلى يقطينة. والأهم من ذلك - سنوضح كيفية إصلاحها. هيا بنا!
\n\nالخطأ رقم 1: "var" السحري وعدم فهم نطاق الرؤية
\n\nكثير من المطورين المبتدئين الذين يتعلمون JavaScript يستخدمون var لتعريف المتغيرات. هذا إرث من المعيار القديم ES5 الذي لا يزال موجودًا في كتب عمرها عقد من الزمن. لكن var يشبه سيارة قديمة بدون وسائد هوائية: يمكنك القيادة، لكن عند أول حادث (اقرأ: خلل) ستعاني بشدة.
ما المشكلة؟
\nvar له نطاق رؤية وظيفي، وليس نطاق كتلة. هذا يعني أن المتغير المُعرّف داخل if أو for سيكون متاحًا خارجهما.
// مثال: خطأ مع var\nfunction testVar() {\n if (true) {\n var x = 10;\n }\n console.log(x); // 10 — يعمل، على الرغم من أن x مُعرّف داخل if\n}\n\ntestVar();\n\nتخيل الآن أن لديك 1000 سطر من الكود في مشروعك. لقد عرّفت var i في حلقة، ثم استخدمت نفس المتغير لاحقًا عن طريق الخطأ - تحصل على خلل لا يمكن تتبعه.
ما الحل الصحيح؟
\nاستخدم let و const. لهما نطاق رؤية كتلي ويتصرفان بشكل متوقع.
// الصحيح: let و const\nfunction testLet() {\n if (true) {\n let y = 20;\n const z = 30;\n }\n console.log(y); // ReferenceError: y is not defined\n}\n\ntestLet();\n\nنصيحة: استخدم دائمًا const افتراضيًا. فقط إذا كان المتغير سيُعاد تعيينه - استخدم let. اترك var في الماضي، مثل الأقراص المرنة.
الخطأ رقم 2: الكلمة المنسية "this" - السياق الذي يُفقد
\n\nالكلمة المفتاحية this في JavaScript تشبه المفاجأة في بيضة الشوكولاتة: لا تعرف أبدًا ما سيظهر. يعتقد المبتدئون غالبًا أن this يشير دائمًا إلى الكائن الحالي. لكن هذا غير صحيح. this يعتمد على كيفية استدعاء الدالة، وليس أين تم تعريفها.
مثال كلاسيكي: فقدان السياق في callback
\n\nconst user = {\n name: 'آنا',\n greet: function() {\n console.log('مرحبًا، ' + this.name);\n }\n};\n\nuser.greet(); // مرحبًا، آنا — يعمل\n\nsetTimeout(user.greet, 1000); // مرحبًا، undefined — السياق مفقود!\n\nلماذا يحدث هذا؟ لأن setTimeout يستدعي الدالة كدالة عادية، وليس كطريقة لكائن. في هذه الحالة، يشير this إلى الكائن العام (في المتصفح - window)، الذي ليس لديه name.
كيفية الإصلاح؟
\nثلاث طرق:
\n- \n
- الدالة السهمية (Arrow function) - لا تنشئ
thisخاصًا بها، بل تأخذه من السياق الخارجي. \n - طريقة
.bind()- تربط السياق بشكل دائم. \n - تخزين مرجع لـ
this(طريقة قديمة، من الأفضل عدم استخدامها). \n
// الإصلاح: الدالة السهمية\nconst user = {\n name: 'آنا',\n greet: function() {\n console.log('مرحبًا، ' + this.name);\n }\n};\n\nsetTimeout(() => user.greet(), 1000); // مرحبًا، آنا\n\n// أو باستخدام bind\nsetTimeout(user.greet.bind(user), 1000); // مرحبًا، آنا\n\n