إن تعلم لغة البرمجة له جانبان فقط: أحدهما بناء جملة والآخر هو نوع البيانات. بناء جملة اللغات التي تشبه C ليست أكثر من إذا ، في حين ، للوظائف ، والعمليات الحسابية ، وما إلى ذلك ، واللغات الموجهة للكائنات تتم إضافة إلى كائن.
بناء الجملة هو مجرد مجموعة من القواعد التي وضعها مصممي اللغة مسبقًا. تختلف قواعد اللغات المختلفة ، لكن لديهم جميعًا بعض النقاط المشتركة. بالنسبة لأولئك الذين يعرفون بلغتين أو لغتين برمجة ، غالبًا ما لا تكون القواعد مشكلة عند تعلم لغات البرمجة الأخرى (بالطبع ، إذا كنت تتعلم لغات تشبه c ، فستستغرق الأمر بالتأكيد بعض الوقت للمشاركة في LISP للمرة الأولى). غالبًا ما يكون تركيز التعلم على أنواع البيانات والعمليات ذات الصلة ، وليس هناك قول قديم: "بنية البيانات + خوارزمية = برنامج"! ثانياً ، فإن بناء جملة بعض اللغات نفسها لديه مشاكل في التصميم (JavaScript أكثر من ذلك) ، لذلك لا نحتاج إلى البحث في هذه النقاط. بالطبع ، إذا ادعت أن تكون مهووسًا ، فيمكنك اللعب معها.
ستقدم هذه المقالة مقدمة مفصلة لأنواع البيانات في JavaScript.
نوع ضعيف مقابل النوع القوي
بالنظر إلى فلسفة تصميم JavaScript ، تم تصميم JavaScript كلغة ضعيفة.
الحديث عن هذا ، من المحتم الحديث عن الفرق بين الأنواع الضعيفة والأنواع القوية.
يعتقد بعض الناس عن طريق الخطأ أن الفرق بين الاثنين هو أن "اللغة التي كتبت بقوة تحتاج إلى الإشارة إلى نوعها عند إعلان متغير ، في حين أن أحدهما مكتوب بشكل ضعيف لا يستخدمه". في الواقع ، هذا الرأي خطأ. على سبيل المثال ، مقتطف كود Java التالي:
نسخة الكود كما يلي:
String s = "Hello" ؛
int l = s.getBytes (). الطول ؛
كيف يعرف المترجم أن الطول هو تعبير قانوني؟ وذلك لأن المترجم يعرف أن نوع بيانات S هو سلسلة. عندما يتم استدعاء طريقة getBytes للسلسلة ، يكون نوع بيانات قيمة الإرجاع بايت [] ، لذلك. الطول هو تعبير قانوني.
الفرق الحقيقي بين الاثنين هو:
في اللغات المكتوبة بقوة ، يمكن تحديد نوع كل تعبير في وقت الترجمة ، ولا يُسمح إلا بالعمليات التي تنطبق على هذا النوع ؛
تسمح لغات النوع الضعيف بفرض أي عملية على أي نوع ، ولكن قد تقوم هذه العملية بالإبلاغ عن خطأ في وقت التشغيل.
نوع البيانات
وفقًا لمواصفات ECMASCRIPT 5.1 ، هناك ستة أنواع من البيانات في JavaScript ، وهي: غير محددة ، فارغة ، منطقية ، رقم ، سلسلة ، والكائن. تنتمي الخمسة الأوائل إلى الأنواع الأساسية ، والآخر ينتمي إلى أنواع الكائنات.
أنواع البيانات الأساسية
يحتوي النوع غير المحدد على قيمة واحدة فقط ، وهي غير محددة ، والتي تعني "القيمة الفارغة" ، والتي تنطبق على جميع أنواع البيانات.
يحتوي النوع الفارغ على قيمة واحدة فقط ، وهي فارغة ، والتي تعني "لا كائن" وينطبق فقط على أنواع الكائنات.
النوع المنطقي له قيمتان ، صحيحان وخاطئان
قيم رقم النوع هي مجموعات من أرقام الفاصلة العائمة 64 بت التي تتبع معيار IEEE 754 ، على غرار Java's Double. لا يوجد بنية بيانات عدد صحيح. بالإضافة إلى ذلك ، هناك ثلاث قيم خاصة: NAN ، اللانهاية ، -infinity
قيمة سلسلة النوع هي مجموعة من أحرف Unicode المحدودة. يجب أن تكون محاطة بـ "أو".
فارغة وغير محددة
يمثل كل من Null وغير المحدد مفهوم "غير القيمة" ، إذا تم تمييزه تمامًا:
- فارغة تعني فارغة
- غير محدد يعني أنه غير موجود. هذه القيمة هي جميع المتغيرات دون التهيئة ، والمعلمات المفقودة في الوظيفة ، ولا توجد قيمة إرجاع صريحة.
في لغات أخرى ، يتم استخدام واحد فقط فارغ لتمثيل القيم الخالية. لماذا يوجد غير محدد في JavaScript؟ هذا ناتج عن أسباب تاريخية:
يعتمد JavaScript بناء جملة Java ، ويقسم الأنواع إلى أنواع أساسية وأنواع الكائنات. في Java ، يتم استخدام Null لتمثيل كائنات فارغة ، ويرثها JavaScript كأمر مسلم به ؛ باللغة C ، يكون NULL 0 عند تحويله إلى رقم ، ويعتمد JavaScript أيضًا نفس الطريقة:
نسخة الكود كما يلي:
> الرقم (فارغ)
0
> 5 + فارغة
5
في JavaScript 1.0 ، لا يوجد استثناء حتى الآن. لبعض الاستثناءات (لا توجد متغيرات تهيئة ، والمعلمات المفقودة عند استدعاء وظائف ، وما إلى ذلك) ، يجب تمييزها كقيمة خاصة. NULL هو خيار جيد ، لكن بريندان إيتش يريد تجنب الأمرين التاليين:
- لا ينبغي أن تحتوي هذه القيمة الخاصة على سمة مرجعية ، لأنها خاصة بكائن
- لا ينبغي تحويل هذه القيمة الخاصة إلى 0 ، لأنه ليس من السهل اكتشاف الأخطاء في البرنامج
لهذا السببين ، اختار بريندان إيتش غير محدد ، والذي يمكن إجباره على نان.
نسخة الكود كما يلي:
> الرقم (غير محدد)
نان
> 5 + غير محددة
نان
النتائج مختلفة تمامًا عند التعامل مع كائنات JSON:
نسخة الكود كما يلي:
> json.parse (خالية)
باطل
> json.parse (غير محدد)
// firfox syntaxerror: json.parse: حرف غير متوقع في السطر 1 العمود 1 من بيانات JSON
// Chrome Syntaxerror: رمز غير متوقع u
> json.stringify (NULL)
"باطل"
> json.stringify (غير محدد)
غير محدد
نوع الكائن
كلغة البرمجة النصية ، تحتوي JavaScript نفسها على وظائف مبسطة للغاية ، ويتم توفير العديد من الوظائف (قراءة الملفات والكتابة ، الشبكات ، إلخ) من خلال بيئة المضيف. الجسر بين بيئة المضيف ولغة JavaScript هو كائنات. توفر بيئة المضيف مجموعة متنوعة من الوظائف من خلال توفير سلسلة من الكائنات التي تتوافق مع بناء جملة JavaScript.
في هذه المقالة في البرمجة الموجهة نحو كائن JavaScript (إذا كنت لا تعرف ماهية النموذج الأولي ، أوصي بشدة بقراءة هذه المقالة) ، فقد أكدت مرارًا وتكرارًا أن الأشياء عبارة عن سلسلة من أزواج القيمة الرئيسية في JavaScript ، تمامًا مثل Hashmap في Java. ومع ذلك ، يمكن أن تحتوي خصائص الكائنات في JavaScript على بعض الواصفات (واصفات الخصائص) ، والتي لا تتوفر في HashMap.
وصول السمة
تنقسم واصفات السمات إلى فئتين:
يحتوي واصف البيانات (واصف البيانات) ، على سلسلة من القيم المنطقية ، للإشارة إلى ما إذا كانت السمة تسمح بالتعديل والحذف.
واصف الملحق ، بما في ذلك وظائف الحصول على وضبط.
كلا الواصفتين كائنات ، وكلاهما لديه خصائص منطقية التالية:
يتم استخدام التكوين لتحديد ما إذا كان الواصف يسمح بالتعديل والحذف. الافتراضي كاذب.
يتم استخدام Enumerable لتحديد ما إذا كان سيتم الوصول إلى الخاصية عندما يتم اجتياز كائن (باستخدام طريقة For ... في الحلقة أو الكائن. الافتراضي كاذب.
بالإضافة إلى السمة الشائعة أعلاه ، يحتوي واصف البيانات على سمتين التاليتين:
- يتم استخدام القيمة لتحديد قيمة هذه الخاصية ، الافتراضي غير محدد
- يتم استخدام القابل للكتابة لتحديد ما إذا كانت قيمة الخاصية تسمح بتغيير قيمة الخاصية. الافتراضي كاذب
هناك خصائصان لوصفات الوصول:
- يتم استخدام GET لتحديد الملحق (getter ، وظيفة بشكل أساسي) عند الوصول إلى الخاصية ، وقيمة الإرجاع للملحق هي قيمة الخاصية. الافتراضي غير محدد
- يتم استخدام SET لتحديد المقيِّم (Setter ، وظيفة بشكل أساسي) عند الوصول إلى هذه الخاصية. المقيِّم يقبل المعلمة. الافتراضي غير محدد
يمكننا استخدام Object.DefineProperty لتعيين واصف خاصية الكائن. على سبيل المثال:
نسخة الكود كما يلي:
// باستخدام __proto__
Object.DefineProperty (OBJ ، 'Key' ، {
__proto__: NULL ، // لا توجد خصائص ورثية
القيمة: "ثابت" // لا يمكن تعداده
// غير قابل للتكوين
// غير قابل للكتابة
// كإعدادات افتراضية
}) ؛
من المثال أعلاه ، يمكننا أن نرى أن الواصفات لها خصائص الميراث. قمنا بتعيين __proto__ لكائن الوصف بشكل صريح ، مما يتجنب وراثة السمات المقابلة من Object.prototype. بالطبع ، يمكننا أيضًا تعيين جميع خصائص الوصف بشكل صريح:
نسخة الكود كما يلي:
// كونها صريحة
Object.DefineProperty (OBJ ، 'Key' ، {
التعداد: خطأ ،
قابلة للتكوين: خطأ ،
قابلة للكتابة: خطأ ،
القيمة: "ثابت"
}) ؛
هذا التأثير هو نفس الجزء الأول من الكود.
إليك مثال آخر على واصف الوصول:
نسخة الكود كما يلي:
// مثال على خاصية كائن تمت إضافتها مع DefineProperty مع واصف خاصية ملحق
var bvalue = 38 ؛
Object.DefineProperty (OBJ ، 'Key' ، {
الحصول على: function () {return bvalue ؛ } ،
المجموعة: وظيفة (newValue) {bvalue = newValue ؛ } ،
التعداد: صحيح ،
قابل للتكوين: صحيح
}) ؛
تجدر الإشارة إلى أنه لا يمكن الخلط بين واصفات الوصول وواصفات البيانات. من الخطأ كتابة ما يلي:
نسخة الكود كما يلي:
// لا يمكنك محاولة خلط كليهما:
Object.DefineProperty (OBJ ، "الصراع" ، {
القيمة: 0x9F91102 ،
الحصول على: function () {return 0xdeadbeef ؛ }
}) ؛
// يلقي typeerror: يجب ألا تحدد واصفات الخصائص قيمة
// أو قابلة للكتابة عند تحديد getter أو setter
نوع
إذا كنت تريد معرفة نوع المتغير في وقت التشغيل ، فيمكنك استخدام مشغل typeof. قيمة إرجاع typeof كما يلي:
الشيء الوحيد الذي يجب الإشارة إليه هو typeof null == "كائن". وفقًا لمعايير ECMASCRIPT 5.1 ، يجب أن يكون النوع الفارغ نوعًا أساسيًا. لماذا يتم إرجاع الكائن هنا؟ السبب هذا:
في JavaScript 1.0 ، يتم تمثيل القيمة في JavaScript بهيكل مثل علامة النوع والقيمة الفعلية. علامة نوع الكائن هي 0 ، ويمثل NULL مؤشرًا فارغًا (0x00) بلغة C ، وبالتالي فإن علامة نوع NULL هي 0.
ما سبق هو المحتوى الكامل لهذه المقالة. يرجى الرجوع إليها إذا كنت في حاجة إليها.