مرحبا بالجميع! في نهاية سبتمبر ،
سيبدأ تدفق جديد من دورة
"Fullstack JavaScript Developer" في
OTUS . تحسبا لبدء الفصول الدراسية ، نريد أن نطلعكم على مقال مؤلف أعد خصيصًا لطلاب الدورة.
مؤلف المقال: بافل ياكوبوف
المعاينة. أريد أن أشير على الفور إلى أنه في هذه المقالة يتم فحص الموضوعات المألوفة لـ "النينجا" ، والهدف من هذا المقال هو جعل المبتدئين يفهمون بشكل أفضل بعض الفروق الدقيقة في اللغة ، ولا يضيعون في المهام التي غالباً ما تُعطى أثناء المقابلة - بعد كل شيء ، لا علاقة للمهام بالتطور الحقيقي ، وأولئك الذين يقدمونها ، في معظم الأحيان بهذه الطريقة يحاولون فهم مدى معرفتك لجافا سكريبت جيدًا.

أنواع الذاكرة المرجعية
كيف بالضبط يتم تخزين البيانات في جافا سكريبت؟ تبدأ العديد من دورات البرمجة في التوضيح مع الكلاسيكية: المتغير هو نوع من "المربع" الذي نقوم بتخزين بعض البيانات فيه. ما هي الأنواع ، على ما يبدو ، لا يبدو الأمر مهمًا بالنسبة للغات ذات الكتابة الديناميكية: سيقوم المترجم "بلع" أي نوع من أنواع البيانات وتغيير النوع ديناميكيًا إذا لزم الأمر ، ويجب ألا تفكر في أنواع المتغيرات وكيفية معالجتها. أيها بالطبع خاطئة ، وبالتالي سنبدأ مناقشة اليوم مع الميزات التي غالباً ما تفلت من العقاب: كيف يتم تخزين المتغيرات في جافا سكريبت - في شكل بدائية (نسخ) أو في شكل روابط.
سنقوم على الفور بسرد أنواع المتغيرات التي يمكن تخزينها في شكل بدائية: هذه
boolean
،
null
،
undefined
،
Number
،
String
،
Symbol
،
BigInt
. عندما نواجه متغيرات معلنة بشكل منفصل مع نوع البيانات هذا ، يجب أن نتذكر أنه أثناء التهيئة الأولية ، يقومون بإنشاء خلية ذاكرة - ويمكن تعيينها ونسخها ونقلها وإعادتها حسب القيمة.
يعتمد باقي JavaScript على مناطق الذاكرة المشار إليها. لماذا هم بحاجة؟ حاول منشئو اللغة إنشاء لغة تُستخدم فيها الذاكرة قدر الإمكان (وهذا لم يكن جديدًا تمامًا في ذلك الوقت). لتوضيح ذلك ، تخيل أنك بحاجة إلى تذكر أسماء ثلاثة زملاء عمل جدد - أسماء جديدة تمامًا ، ولتعزيز المقارنة ، زملائك الجدد من الهند أو الصين بأسماء غير عادية بالنسبة لك. تخيل الآن أن زملائك يتم استدعاؤهم مثلك وصديقك المفضلان في المدرسة. في أي موقف سيكون من الأسهل تذكره؟ هنا ، ذاكرة شخص وجهاز كمبيوتر يعمل بشكل مشابه. فيما يلي بعض الأمثلة المحددة:
let x = 15;
وبالتالي ، إذا واجهت مهمة مماثلة في مقابلة ، فحاول أن تفهم على الفور نوع البيانات الموجودة أمامك - من أين أتت وكيف حصلت على القيمة ، كنوع بدائي ، أو كمرجع.

سياق العمل
من أجل فهم كيفية عمل السياق في JS ، تحتاج إلى دراسة بضع نقاط:
- مستوى الرؤية العالمية / المحلية.
- الفرق في السياق عند تهيئة المتغيرات في النطاق العام / المحلي.
- وظائف السهم.
ذات مرة ، مرة أخرى في ES5 ، كان كل شيء بسيطًا جدًا: لم يكن هناك سوى إعلان متغير باستخدام var ، والذي اعتبر عندما تم الإعلان عنه في تدفق البرنامج عموميًا (مما يعني أن المتغير قد تم تعيينه كخاصية لكائن عمومي ، مثل
window
أو
global
). ثم
let
و
const
جاء إلى المشهد ، الذين يتصرفون بطريقة مختلفة إلى حد ما: لم يتم تعيينهم للكائن العمومي ، ويتم تخزينهم في الذاكرة بشكل مختلف ، مع التركيز على نطاق الكتلة. الآن يعتبر var بالفعل قديمًا ، لأن استخدامه يمكن أن يؤدي إلى انسداد النطاق العالمي ، وبالإضافة إلى ذلك ،
let
نبدو أكثر قابلية للتنبؤ به.
1. لذلك ، لفهم أنه من المفيد أن نفهم بوضوح ما هو النطاق في جافا سكريبت (النطاق). إذا تم الإعلان عن متغير في النطاق العمومي باستخدام توجيه
let
، فلن يتم تعيينه إلى كائن
window
، ولكن يتم حفظه عالميًا.
دعنا ننتقل إلى المهام التي غالبًا ما تكون مبتدئة في الأسئلة السياقية في المقابلة.
//: ? let x = 15; function foo(){ let x = 13; return x; } console.log(x)// 15 foo(); console.log(x)// x = foo(); console.log(x)// return ,
2. في الوقت نفسه ، ليس كل المبتدئين على دراية بكيفية قراءة مترجم JavaScript للشفرة: في الواقع ، يقرأها مرتين ، وهي المرة الأولى التي تقرأ فيها شفرة الوظائف المعلنة على أنها إعلان وظيفي (وهي جاهزة لتنفيذها في القراءة الثانية الحقيقية والتنفيذ الفعلي ). هناك خدعة صغيرة أخرى مرتبطة بـ
var
let
: في المرة الأولى التي يتم فيها قراءة المتغير مع توجيه
var
، يتم ضبطه على
undefined
. ولكن مع
let
لا يمكن إجراء مكالمة سابقة لأوانها على الإطلاق:
console.log(x); console.log(y) var x = 42; let y = 38;
3. اكتسبت وظائف السهم التي ظهرت في ES6 شعبية بسرعة - تم تبنيها بسرعة من قبل المبرمجين على
Node.js (بسبب التحديث السريع للمحرك) و
React (بسبب ميزات المكتبة والاستخدام المحتم لـ Babel). فيما يتعلق بالسياق ، تلتزم وظائف السهم بالقاعدة التالية: لا ترتبط
this
. نوضح هذا:
var x = 4; var y = 4; function mult(){ return this.x * this.y; } let foo = mult.bind(this); console.log(foo()); let muliply = ()=>x*y; console.log(muliply()); /* x y let, function declaration */

أنواع البيانات وما ينطبق على
دعنا نقول على الفور: المصفوفة هي في الأساس كائن ، وفي جافا سكريبت ، هذا ليس هو الاختلاف الأول لكائن - الخريطة ، مجموعة WeakSet ، Set ، والمجموعات تؤكد ذلك.
لذلك ، تعد المصفوفة كائنًا ، وفرقها عن كائن عادي في JS هو ، أولاً وقبل كل شيء ، سرعة عمل أعلى بسبب تحسين الفهرسة ، وثانيًا ، الميراث من Array.prototype ، والذي يوفر مجموعة أكبر من الطرق ، وهذا هو السبب الأخ الأكبر »
Object.prototype
.
console.log(typeof({})) console.log(typeof([])) console.log(typeof(new Set)) console.log(typeof(new Map)) //
التالي في قائمة انتظار الشذوذ في أنواع البيانات
null
. إذا سألت JavaScript عن نوع البيانات الخالية ، فسنحصل على إجابة لا لبس فيها. ومع ذلك ، هنا لن يتم الاستغناء عن بعض الحيل:
let x = null; console.log(typeof(x)); //! , null objet, ? console.log(x instanceof Object.prototype.constructor); //false // ! )
تجدر الإشارة إلى أن
null
عبارة عن نوع بيانات خاص - على الرغم من أن بداية المثال السابق تشير بدقة إلى نوع آخر. من أجل فهم أفضل لما تمت إضافة هذا النوع المعين إلى اللغة ، يبدو لي أنه يجدر استكشاف أساسيات بناء جملة C ++ أو C #.
وبالطبع ، في المقابلات غالباً ما يصادف مثل هذه المهمة ، التي تتعلق خصوصيتها بالكتابة الديناميكية:
console.log(null==undefined);//true console.log(null===undefined);// false
هناك عدد كبير من الحيل المرتبطة بنوع الكتابة عند المقارنة في JS ؛ لسنا قادرين جسديًا على جلبها جميعًا إلى هنا. نوصي بالإشارة إلى
"ماذا بحق الجحيم JavaScript" .

ميزات غير منطقية تركت في اللغة أثناء عملية التطوير
إضافة خطوط. في الواقع ، لا يمكن أن تعزى إضافة السلاسل بالأرقام إلى أخطاء في تطوير اللغة ، ولكن في سياق جافا سكريبت ، أدى ذلك إلى أمثلة معروفة تعتبر غير منطقية بما فيه الكفاية:
codepen.io/pen/؟editors=0011 let x = 15; let y = "15"; console.log(x+y);// "" console.log(xy); //
حقيقة أن الجمع ببساطة يضيف أسطرًا بالأرقام غير منطقي نسبيًا ، لكن عليك فقط تذكر ذلك. قد يكون هذا غير عادي على وجه الخصوص لأن اللغتين الأخريين المفسرتين الشائعتين والمستخدمتين على نطاق واسع في تطوير الويب - PHP و Python - لا يلقيان مثل هذه الحيل بإضافة السلاسل والأرقام ويتصرفان بشكل أكبر في مثل هذه العمليات.
الأمثلة المشابهة أقل شهرة ، على سبيل المثال ، مع NaN:
console.log(NaN == NaN); //false console.log(NaN > NaN); //false console.log(NaN < NaN); //false … ... , NaN? console.log(typeof(NaN)); // number
غالبًا ما تجلب NaN مفاجآت غير سارة ، على سبيل المثال ، إذا قمت بتكوين تدقيق النوع بشكل غير صحيح.
مثال 0.1 +0.2 أكثر شهرة - لأن هذا الخطأ مرتبط بتنسيق IEEE 754 ، والذي يستخدم أيضًا ، على سبيل المثال ، في بيثون "الرياضي".
نحن ندرج أيضًا خللًا أقل شهرة برقم إبسيلون ، والسبب الذي يكمن في نفس السياق:
console.log(0.1+0.2)// 0.30000000000000004 console.log(Number.EPSILON);// 2.220446049250313e-16 console.log(Number.EPSILON + 2.1) // 2.1000000000000005
والأسئلة الأكثر تعقيدًا قليلاً:
Object.prototype.toString.call([])// ? // -> '[object Array]' Object.prototype.toString.call(new Date) // Date? // -> '[object Date]'

مراحل معالجة الأحداث
العديد من المبتدئين لا يفهمون أحداث المتصفح. غالبًا ما تكون غير مألوفة هي أهم المبادئ الأساسية التي تعمل بها أحداث المستعرض - الاعتراض والارتقاء والأحداث الافتراضية. الأمر الأكثر غموضًا من وجهة نظر المبتدئين هو ظهور حدث لا شك في أنه مبرر في البداية يثير أسئلة. يعمل الإطار المنبثق على النحو التالي: عند النقر فوق عنصر DOM متداخل ، لا يتم إطلاق الحدث عليه فحسب ، ولكن أيضًا على الأصل ، إذا تم تثبيت معالج له مثل هذا الحدث على الأصل.
في حالة ظهور حدث ما ، فقد نحتاج إلى إلغائه.
// , function MouseOn(e){ this.style.color = "red"; e.stopPropagation(); // }
بالإضافة إلى ذلك ، غالبًا ما يمثل إلغاء الأحداث التي تحدث افتراضيًا مشكلة بالنسبة للمبتدئين. هذا مهم بشكل خاص عند تطوير النماذج - لأن التحقق من صحة النموذج ، على سبيل المثال ، يجب القيام به من جانب العميل ومن جانب الخادم:
codepen.io/isakura313/pen/GRKMdaR؟editors=0010 document.querySelector(".button-form").addEventListener( 'click', function(e){ e.preventDefault(); console.log(' . , ') } )
يمكن أن يؤدي إلغاء تعرُّف حدث ما أيضًا إلى إحداث بعض المشاكل: على سبيل المثال ، يمكنك إنشاء ما يسمى بـ "المنطقة الميتة" والتي لن يعمل فيها الشيء الضروري - على سبيل المثال ، حدث عنصر غير محظوظ بالقرب منه.
شكرا لكم جميعا على اهتمامكم! فيما يلي بعض الروابط المفيدة التي يمكنك من خلالها استخلاص الكثير من المعلومات المفيدة:
هذا كل شيء. نحن في انتظارك في
الندوة المجانية على الإنترنت ، والتي ستعقد في 12 سبتمبر.