القائمة الرئيسية

الصفحات

مما يتكون جافا سكريبت؟



مما يتكون جافا سكريبت؟


خلال السنوات القليلة الأولى من استخدام جافا سكريبت ، شعرت بأنني احتيال. على الرغم من أنني تمكنت من إنشاء مواقع ويب بأطر عمل ، فقد كان هناك شيء مفقود. كنت أخشى مقابلات عمل جافا سكريبت لأنني لم أكن أعلم جيدًا عن الأساسيات.

على مر السنين ، قمت بتشكيل نموذج عقلي لجافا سكريبت أعطاني الثقة. هنا ، أشارك نسخة مضغوطة جدًا منه. إنه منظم مثل المسرد ، حيث يحصل كل موضوع على جمل قليلة.

أثناء قراءتك لهذا المنشور ، حاول الحفاظ على النتيجة الذهنية حول مدى ثقتك بنفسك في كل موضوع. لن أحكم عليك إذا كان عدد قليل منهم في عداد المفقودين! في نهاية هذا المنشور ، هناك شيء قد يساعد في هذه الحالة.

القيمة : مفهوم القيمة مجردة بعض الشيء. إنه "شيء". إن قيمة JavaScript هي ما يعنيه الرقم ، أو ما هي نقطة الهندسة. عندما يعمل برنامجك ، فإن عالمه مليء بالقيم. أرقام مثل 1، 2و 420هي قيم، ولكن حتى بعض الأشياء الأخرى، مثل هذه الجملة: "Cows go moo". ليس كل شيء ذو قيمة بالرغم من ذلك. الرقم قيمة ، لكن ifالبيان ليس كذلك. سنلقي نظرة على بعض أنواع القيم المختلفة أدناه.

نوع القيمة : هناك عدة أنواع مختلفة من القيم. على سبيل المثال ، أرقام مثل 420، وسلاسل مثل "Cows go moo"، وكائنات ، وبعض الأنواع الأخرى. يمكنك معرفة نوع من القيمة من خلال وضعه typeofأمامه. على سبيل المثال ، console.log(typeof 2)يطبع "number".

القيم البدائية : بعض أنواع القيم "بدائية". وهي تشمل أرقامًا وسلاسلًا وبعض الأنواع الأخرى. الشيء الغريب في القيم البدائية هو أنه لا يمكنك إنشاء المزيد منها ، أو تغييرها بأي شكل من الأشكال. على سبيل المثال ، في كل مرة تكتب فيها 2، تحصل على نفس القيمة 2. لا يمكنك "إنشاء" آخر 2في برنامجك ، أو جعل 2 القيمة "تصبح" 3. وينطبق هذا أيضًا على السلاسل.
nullوundefined : هذان قيمتان خاصتان. إنها خاصة لأن هناك الكثير من الأشياء التي لا يمكنك فعلها بها - غالبًا ما تسبب أخطاء. عادة ، nullيمثل أن بعض القيمة مفقودة عن قصد ، undefinedويمثل أن القيمة مفقودة عن غير قصد. ومع ذلك ، عند استخدام أي من ترك للمبرمج. إنها موجودة لأنه في بعض الأحيان يكون من الأفضل أن تفشل العملية بدلاً من المتابعة بقيمة مفقودة.

المساواة : مثل "القيمة" ، تعد المساواة مفهومًا أساسيًا في جافا سكريبت. نقول قيمتين متساويتين عندما ... في الواقع ، لن أقول ذلك أبدًا. إذا قيمتين على قدم المساواة، وهو ما يعني أنها هي نفس القيمة. لا قيمتين مختلفتين ، ولكن واحدة! على سبيل المثال، "Cows go moo" === "Cows go moo"و 2 === 2لأن 2 هو 2 . لاحظ أننا نستخدم ثلاث علامات متساوية لتمثيل مفهوم المساواة هذا في JavaScript.

المساواة الصارمة : مثلما ورد أعلاه.
المساواة المرجعية : نفس ما ورد أعلاه.
مساواة فضفاضة : عوف ، هذا مختلف! المساواة فضفاضة هي عندما نستخدم اثنين من علامات المساواة ( ==). يمكن اعتبار الأشياء متساوية بشكل فضفاض حتى لو كانت تشير إلى قيم مختلفة تبدو متشابهة (مثل 2و "2"). تمت إضافته إلى JavaScript في وقت مبكر للراحة وتسبب في ارتباك لا نهاية له منذ ذلك الحين. هذا المفهوم ليس أساسيًا ، ولكنه مصدر شائع للأخطاء. يمكنك أن تتعلم كيف تعمل في يوم ممطر ، لكن الكثير من الناس يحاولون تجنبه.
Literal : حرفيا عندما تشير إلى قيمة عن طريق كتابتها حرفيا في برنامجك. على سبيل المثال ، 2هو رقم حرفي ، "Banana"وهو سلسلة حرفية .

المتغير : يتيح لك المتغير الرجوع إلى بعض القيمة باستخدام الاسم. على سبيل المثال ، let message = "Cows go moo". يمكنك الآن الكتابة messageبدلاً من تكرار نفس الجملة في كل مرة في التعليمات البرمجية الخاصة بك. يمكنك التغيير لاحقًا messageللإشارة إلى قيمة أخرى ، مثل message = "I am the walrus". لاحظ أن هذا لا يغير القيمة نفسها ، ولكن فقط حيث messageيشير إلى ، مثل "سلك". وأشار إلى "Cows go moo"، والآن يشير إلى "I am the walrus".

النطاق : سيكون الأمر ممتعًا إذا كان هناك messageمتغير واحد فقط في البرنامج بأكمله. بدلاً من ذلك ، عندما تحدد متغيرًا ، يصبح متاحًا في جزء من برنامجك. هذا الجزء يسمى "نطاق". هناك قواعد حول كيفية عمل نطاق، ولكن عادة يمكنك البحث عن أقرب {و }الأقواس حول المكان الذي تعريف المتغير. هذا "كتلة" التعليمات البرمجية هو نطاقها.
الواجب : عندما نكتب message = "I am the walrus"، نغير messageالمتغير للإشارة إلى "I am the walrus"القيمة. وهذا ما يسمى المتغير أو الكتابة أو تعيين المتغير.

letvs constvsvar : عادة ما تريد let. إذا كنت تريد منع التعيين لهذا المتغير ، يمكنك استخدامه const. (بعض قواعد التعليمات البرمجية وزملاء العمل متحذلقون وتجبرك على استخدام constعندما يكون هناك مهمة واحدة فقط.) تجنب varإذا استطعت لأن قواعد تحديد النطاق مربكة.

الكائن : الكائن هو نوع خاص من القيمة في JavaScript. الشيء الرائع في الأشياء هو أنه يمكن أن يكون لها اتصالات بقيم أخرى. على سبيل المثال ، {flavor: "vanilla"}يحتوي الكائن على flavorخاصية تشير إلى "vanilla"القيمة. فكر في شيء كقيمة "خاصة بك" مع "أسلاك" منه.

الخاصية : الخاصية تشبه "سلك" يلتصق بجسم ما ويشير إلى قيمة ما. قد يذكرك بمتغير: له اسم (مثل flavor) ويشير إلى قيمة (مثل "vanilla"). ولكن على عكس المتغير ، فإن خاصية "تعيش" في الكائن نفسه وليس في مكان ما في التعليمات البرمجية (النطاق). تعتبر الخاصية جزءًا من الكائن - ولكن القيمة التي تشير إليها ليست كذلك.

Object Literal : حرفيا الكائن هو طريقة لإنشاء قيمة كائن عن طريق كتابتها حرفيا في برنامجك ، مثل {}أو {flavor: "vanilla"}. في الداخل {}، يمكن أن يكون لدينا عدة property: valueأزواج مفصولة بفواصل. يتيح لنا هذا تحديد المكان الذي تشير إليه "الأسلاك" من جسمنا.

وجوه الهوية : ذكرنا في وقت سابق ان 2هو قدم المساواة ل 2(وبعبارة أخرى، 2 === 2) لأنه كلما نكتب 2، نحن "استدعاء" نفس القيمة. ولكن كلما نكتب {}، سنحصل دائمًا على قيمة مختلفة ! لذلك {}هو لا يساوي لآخر {}. جرب هذا في وحدة التحكم: {} === {}(النتيجة خاطئة). عندما يلتقي الكمبيوتر 2في التعليمات البرمجية الخاصة بنا ، فإنه يعطينا دائمًا نفس 2القيمة. ومع ذلك ، تختلف حرفية الكائن: عندما يلتقي الكمبيوتر {}، فإنه ينشئ كائنًا جديدًا ، وهو دائمًا قيمة جديدة . إذن ما هي هوية الكائن؟ إنها مصطلح آخر للمساواة ، أو نفس القيم. عندما نقول " aوbلها نفس الهوية "، فإننا نعني" aو bأشر إلى نفس القيمة "( a === b). عندما نقول " aو bهويات مختلفة"، فإننا نعني " aو bأشر إلى مختلف القيم" ( a !== b).
تدوين النقطة : عندما تريد قراءة خاصية من كائن أو تعيينها ، يمكنك استخدام .تدوين النقطة ( ). على سبيل المثال، إذا كان متغير iceCreamنقاط إلى كائن به الخاصية flavorنقاط ل "chocolate"والكتابة iceCream.flavorسوف اعطيكم "chocolate".

تدوين القوس : في بعض الأحيان لا تعرف اسم العقار الذي تريد قراءته مسبقًا. على سبيل المثال ، ربما تريد iceCream.flavorأحيانًا القراءة وأحيانًا تريد القراءة iceCream.taste. []يتيح لك تدوين الأقواس ( ) قراءة الخاصية عندما يكون اسمها متغيرًا. على سبيل المثال ، دعنا نقول ذلك let ourProperty = 'flavor'. ثم iceCream[ourProperty]سيعطينا "chocolate". الغريب، يمكننا استخدامها عند إنشاء كائنات جدا: { [ourProperty]: "vanilla" }.

طفرة : نحن نقول هو كائن تحور عندما يتغير شخص ما ممتلكاتها للإشارة إلى قيمة مختلفة. على سبيل المثال، إذا نعلن let iceCream = {flavor: "vanilla"}، نحن يمكن بعد يتحور مع iceCream.flavor = "chocolate". لاحظ أنه حتى لو اعتدنا constأن نعلن iceCream، لا يزال بإمكاننا التحور iceCream.flavor. هذا لأنه constسيمنع فقط التخصيصات iceCream للمتغير نفسه ، لكننا قمنا بتحوير خاصية ( flavor) للكائن الذي أشار إليه. أقسم بعض الأشخاص على استخدامهم constتمامًا لأنهم يجدون هذا مضللاً للغاية.

Array : المصفوفة هي كائن يمثل قائمة من الأشياء. عندما تكتب صفيفًا حرفيًا مثل ["banana", "chocolate", "vanilla"]، فأنت تقوم بشكل أساسي بإنشاء كائن تسمى خاصيته 0نقاطًا إلى "banana"قيمة السلسلة ، وخاصية تسمى 1نقاطًا إلى "chocolate"القيمة ، وخاصية تسمى 2نقاطًا إلى "vanilla"القيمة. سيكون مزعجًا للكتابة {0: ..., 1: ..., 2: ...}ولهذا السبب تعد المصفوفات مفيدة. وهناك أيضا المدمج في بعض الطرق للعمل على المصفوفات، مثل map، filterو reduce. لا تيأس إذا reduceبدت مربكة - إنها مربكة للجميع.

النموذج الأولي : ماذا يحدث إذا قرأنا خاصية غير موجودة؟ على سبيل المثال ، iceCream.taste(لكن ممتلكاتنا تسمى flavor). الجواب البسيط هو أننا سنحصل على undefinedالقيمة الخاصة . الجواب الأكثر دقة هو أن معظم الكائنات في جافا سكريبت لها "نموذج أولي". يمكنك التفكير في النموذج الأولي على أنه خاصية "مخفية" في كل كائن يحدد "مكان النظر إلى التالي". لذلك إذا لم يكن هناك tasteخاصية iceCreamقيد التشغيل ، فسوف تبحث JavaScript عن tasteخاصية في النموذج الأولي الخاص بها ، ثم في النموذج الأولي لهذا الكائن ، وما إلى ذلك ، ولن تعطينا إلا undefinedإذا وصلت إلى نهاية "سلسلة النموذج الأولي" هذه دون العثور عليها .taste. نادرًا ما ستتفاعل مع هذه الآلية مباشرةً ، لكنها تشرح سبب احتواء iceCreamجسمنا علىtoString الطريقة التي لم نحددها أبدًا - إنها تأتي من النموذج الأولي.

الوظيفة : الوظيفة هي قيمة خاصة لغرض واحد: أنها تمثل بعض التعليمات البرمجية في برنامجك . الوظائف مفيدة إذا كنت لا تريد كتابة نفس الرمز عدة مرات. "استدعاء" وظيفة مثل sayHi()تخبر الكمبيوتر بتشغيل التعليمات البرمجية بداخله ثم العودة إلى مكانه في البرنامج. هناك العديد من الطرق لتعريف دالة في JavaScript ، مع وجود اختلافات طفيفة في ما تقوم به.

الحجج (أو المعلمات) : الحجج ندعك تمرير بعض المعلومات إلى وظيفة الخاص بك من المكان الذي يطلق عليه: sayHi("Amelie"). داخل الوظيفة ، يتصرفون على غرار المتغيرات. يطلق عليها إما "الحجج" أو "المعلمات" اعتمادًا على الجانب الذي تقرأه (تعريف الوظيفة أو استدعاء الوظيفة). ومع ذلك ، فإن هذا التمييز في المصطلحات متحيز ، وفي الممارسة العملية يتم استخدام هذين المصطلحين بالتبادل.

التعبير عن الوظيفة : في السابق ، قمنا بتعيين متغير على قيمة سلسلة ، مثل let message = "I am the walrus". اتضح أنه يمكننا أيضًا تعيين متغير لدالة ، مثل let sayHi = function() { }. الشيء بعد =ويسمى هنا التعبير وظيفة . يمنحنا قيمة خاصة (دالة) تمثل جزءًا من التعليمات البرمجية الخاصة بنا ، لذلك يمكننا تسميتها لاحقًا إذا أردنا ذلك.
إعلان وظيفة : فإنه يحصل متعب لكتابة شيء من هذا القبيل let sayHi = function() { }في كل مرة، حتى نتمكن من استخدام نموذج أقصر بدلا من ذلك: function sayHi() { }. وهذا ما يسمى إعلان الوظيفة . بدلاً من تحديد اسم المتغير على اليسار ، نضعه بعد functionالكلمة الأساسية. هذان الأسلوبان قابلان للتبادل في الغالب.

رفع الوظيفة : عادة ، لا يمكنك استخدام متغير إلا بعد إعلانه مع letأو constتم تشغيله. يمكن أن يكون هذا مزعجًا للوظائف لأنها قد تحتاج إلى الاتصال ببعضها البعض ، ومن الصعب تتبع الوظيفة المستخدمة من قبل الآخرين والتي تحتاج إلى تعريفها أولاً. كوسيلة راحة ، عندما (عندما وفقط!) تستخدم بناء جملة تعريف الوظيفة ، لا يهم ترتيب تعريفاتها لأنها تحصل على "رفع". هذه طريقة رائعة لقول ذلك من الناحية المفاهيمية ، يتم نقلهم جميعًا تلقائيًا إلى أعلى النطاق. عند الاتصال بهم ، يتم تحديدهم جميعًا.

this: ربما يكون مفهوم جافا سكريبت الأكثر سوءًا thisهو مثل حجة خاصة للدالة. لا تمررها إلى وظيفة بنفسك. بدلاً من ذلك ، تقوم JavaScript بتمريرها ، اعتمادًا على كيفية استدعاء الوظيفة. على سبيل المثال ، ستحصل المكالمات التي تستخدم .ترميز النقاط - مثل iceCream.eat()- على thisقيمة خاصة من أي شيء قبل .(في مثالنا iceCream). تعتمد قيمة thisداخل دالة على كيفية استدعاء الوظيفة ، وليس حيث يتم تعريفها. المساعدون مثل .bind، .callو .applyالسماح لديك لمزيد من السيطرة على قيمة this.

وظائف السهم : تتشابه وظائف السهم مع تعبيرات الوظائف. قمت بتعريف لهم مثل هذا: let sayHi = () => { }. إنها مختصرة وغالبًا ما تستخدم لواحد بطانات. وظائف السهم محدودة أكثر من الوظائف العادية - على سبيل المثال ، ليس لديهم مفهوم على thisالإطلاق. عندما تكتب thisداخل دالة سهم ، فإنها تستخدم thisأقرب وظيفة "عادية" أعلاه. هذا مشابه لما قد يحدث إذا استخدمت وسيطة أو متغيرًا موجودًا فقط في دالة أعلاه. وهذا يعني عمليًا أن الأشخاص يستخدمون وظائف الأسهم عندما يريدون "رؤية" thisداخلهم كما في التعليمات البرمجية المحيطة بهم.

وظيفة التجليد : عادة، ملزمة وظيفة fلعبارة معينة thisالقيمة والحجج يعني خلق و الجديدة وظيفة أن المكالمات fمع تلك القيم مسبقا. جافا سكريبت لديها مساعد مدمج للقيام بذلك يسمى .bind، ولكن يمكنك أيضًا القيام بذلك يدويًا. كان التجليد طريقة شائعة لجعل الدوال المتداخلة "ترى" نفس قيمة thisالدوال الخارجية. ولكن الآن يتم التعامل مع حالة الاستخدام هذه بواسطة وظائف الأسهم ، لذلك لا يتم استخدام الربط في كثير من الأحيان.

Call Stack : استدعاء دالة يشبه دخول غرفة. في كل مرة نسمي فيها دالة ، تتم تهيئة المتغيرات داخلها من جديد. لذا فإن كل استدعاء دالة يشبه إنشاء "غرفة" جديدة برمزها وإدخالها. متغيرات وظيفتنا "تعيش" في تلك الغرفة. عندما نعود من الوظيفة ، تختفي تلك "الغرفة" بكل متغيراتها. يمكنك تصور هذه الغرف ككومة رأسية من الغرف - مكدس مكالمات . عندما نخرج من دالة ، نعود إلى الوظيفة "أدناه" على مكدس الاستدعاءات.

العودية : العودية تعني أن دالة تستدعي نفسها من داخلها. هذا مفيد عندما تريد تكرار الشيء الذي فعلته للتو في وظيفتك مرة أخرى ، ولكن لحجج مختلفة. على سبيل المثال ، إذا كنت تكتب محرك بحث يزحف على الويب ، collectLinks(url)فقد تقوم وظيفتك أولاً بجمع الروابط من الصفحة ، ثم تطلق على نفسها كل ارتباط حتى يزور جميع الصفحات. العيب مع العودية هو أنه من السهل كتابة رمز لا ينتهي أبدًا لأن الوظيفة تستمر في استدعاء نفسها إلى الأبد. إذا حدث ذلك ، فسيقوم JavaScript بإيقافه بخطأ يسمى "تجاوز سعة المكدس". يطلق عليه بهذه الطريقة لأنه يعني أن لدينا مكالمات وظيفية مكدسة للغاية في مكدس المكالمات الخاص بنا ، وقد تجاوزت حرفياً.

دالة الترتيب الأعلى : دالة الترتيب الأعلى هي وظيفة تتعامل مع وظائف أخرى من خلال أخذها كحجج أو إعادتها. قد يبدو هذا غريبًا في البداية ، ولكن يجب أن نتذكر أن الدوال هي قيم حتى نتمكن من تمريرها - كما نفعل مع الأرقام أو السلاسل أو الأشياء. يمكن الإفراط في استخدام هذا النمط ، ولكنه معبر جدًا في الاعتدال.

رد الاتصال: رد الاتصال ليس بالفعل مصطلح JavaScript. إنه أكثر من نمط. عندما تقوم بتمرير دالة كوسيطة لدالة أخرى ، تتوقع أن تستدعي وظيفتك مرة أخرى لاحقًا . أنت تتوقع "إعادة الاتصال". على سبيل المثال ، setTimeoutيأخذ وظيفة رد الاتصال و ... يتصل بك مرة أخرى بعد انتهاء المهلة. ولكن لا يوجد شيء خاص حول وظائف رد الاتصال. إنها وظائف منتظمة ، وعندما نقول "رد الاتصال" نتحدث فقط عن توقعاتنا.

الإغلاق : عادة ، عند الخروج من دالة ، "تختفي" جميع متغيراتها. هذا لأنه لا شيء يحتاجهم بعد الآن. ولكن ماذا لو أعلنت وظيفة داخل دالة؟ ثم لا يزال من الممكن استدعاء الوظيفة الداخلية في وقت لاحق ، وقراءة متغيرات الوظيفة الخارجية . عمليًا ، هذا مفيد جدًا! ولكن لكي ينجح ذلك ، تحتاج متغيرات الوظيفة الخارجية إلى "البقاء" في مكان ما. لذا في هذه الحالة ، تهتم JavaScript "بالحفاظ على المتغيرات على قيد الحياة" بدلاً من "نسيانها" كما تفعل عادةً. وهذا ما يسمى "الإغلاق". على الرغم من أن عمليات الإغلاق غالبًا ما تُعتبر جانب جافا سكريبت يساء فهمها ، فمن المحتمل أنك تستخدمها عدة مرات في اليوم دون أن تدرك ذلك!
JavaScript مصنوع من هذه المفاهيم ، وأكثر من ذلك. شعرت بالقلق الشديد من معرفتي بجافا سكريبت حتى أتمكن من بناء نموذج عقلي صحيح ، وأود أن أساعد الجيل القادم من المطورين على سد هذه الفجوة في وقت أقرب.









reaction:

تعليقات