بالنسبة لأنواع JavaScript ، يمكن تلخيصها ببساطة على النحو التالي: بالمقارنة مع اللغات المكتوبة بقوة ، فهي لغة نوع ضعيفة (فضفاضة) ؛ هناك أنواع أساسية وأنواع مرجعية ، وهي الفرق هو وجود مساحة ثابتة في ذاكرة المكدس ، ويتم تخزين مؤشر إلى موقع التنفيذ في ذاكرة المكدس دون مساحة ثابتة ويتم تخزين مؤشر إلى موقع التنفيذ في ذاكرة المكدس.
العديد من الكتب في السوق لديها مساحة كبيرة للحديث عنها. ستتحدث هذه المقالة عن عدة جوانب ، والتي قد تتطلب منك أن يكون لديك بعض الفهم البسيط لجافا سكريبت ، وخاصة أنواع جافا سكريبت. إذا لم تفهمها بعد ، فيمكنك التقاط كتاب عن JavaScript وقراءته مرة أخرى.
1. الأنواع الأساسية وأنواع المرجع
1. النوع الأساسي: غير محدد/لاغية/منطقية/رقم/سلسلة
2. نوع المرجع: كائن/صفيف/دالة/تاريخ/regexp/خطأ/خريطة/تعيين ...
لماذا لا يتم تعداد الأنواع المرجعية؟ لأنك تعرف الكثير عن ذلك ، على الأقل في المقالة التي تحدثت عنها هذه كافية. نادراً ما يتم استخدام الآخرين ، وحتى أولئك الذين يحبون الخريطة والمجموعة لا يتم دعمهم بواسطة جميع المتصفحات.
2. حكم نوع JavaScript
هناك نوعان من المشغلين في JavaScript يمكن استخدامه لتحديد الأنواع. إنها نوع و extomof ، لكن الدائرة صغيرة جدًا ، وهي ليست جيدة في ذلك ، وهي غير موثوقة. بعض المواقف صحيحة أيضًا ، لكنها في كثير من الحالات غير موثوقة. فقط انظر إليه وستعرف:
نسخة الكود كما يلي:
// عندما تكون موثوقة:
Typeof 'sofish' // string
سلسلة جديدة ('sofish') مثيل string // true
// عندما يكون غير موثوق به:
Typeof [] // Object
Typeof null // object
مثيل "Sofish" من String // false
أه ~ قد يقسم العديد من مبرمجي JavaScript. معظم الناس لديهم بالفعل مكتبات مثل jQuery عندما يحتاجون إلى استخدام JS. لقد قاموا جميعهم بتغليفها بحيث يمكنك اكتشاف الأنواع بسهولة. بالطبع ، في الواقع ، ليس من المزعج اكتشاف ، لأن الجملة "في JavaScript ، كل شيء هو كائن" ، بالطبع ، كما هو مذكور في العديد من المستندات ، غير المحددة هي في الواقع مجرد سمة عالمية مع Nan و Infinity. ربما تعرف. لكن "الكائن" يمكن أن يساعدنا:
نسخة الكود كما يلي:
/* اكتشاف نوع الكائن
* param: obj {JavaScript Object}
* param: اكتب {string} اسم نوع JS بدءًا من الأحرف الكبيرة
* return: {boolean}
*/
الوظيفة هي (obj ، type) {
return Object.Prototype.ToString.Call (OBJ) .slice (8 ، -1) === type ؛
}
وبهذه الطريقة ، يمكننا استخدام الدالة IS لمساعدتنا في حل الحكم النوع ، وهذه الوظيفة البسيطة لها توافق جيد ويمكن استخدامها في مشروعك. الوضع مثل:
نسخة الكود كما يلي:
IS ('sofish' ، 'string') // true
هو (فارغ ، 'فارغ') // صحيح
هو (مجموعة جديدة () ، "مجموعة") // صحيح
3. تحويل نوع JavaScript
في JavaScript ، يمكن تغيير نوع المتغير (الخصائص). الشيء الأكثر شيوعًا الذي تراه هو التحويل بين السلسلة والرقم. كيف تتحول 1 + '2' إلى 12؟ من الضروري فهم عامل التشغيل + هنا ، وهو عامل رياضي وأيضًا واصلة سلسلة في JavaScript. لذلك ، سوف يرى المبتدئون ظاهرة مثيرة للاهتمام. عند استخدام علامة + ، في بعض الأحيان ، لا يكون الحساب هو ما يريدون ، ولكن يمكن استخدام الإشارة دائمًا الحصول على الإجابة "الصحيحة".
نسخة الكود كما يلي:
1 + '2' // '12'
1 + ( + '2') // 3
1 - '2' // -1
هذا هو في الواقع بسبب الدور المزدوج لـ +. في الكود أعلاه ، يمكنك ملاحظة أن التعبير الثاني يستخدم علامة + أمام السلسلة ، مما يجبر فئتها على تحويلها إلى رقم. بالنسبة لفهم تحويل نوع JavaScript ، في معظم الحالات ، يكفي أن نفهم + دور مزدوج. يمكن تعديل فئات أخرى مفهومة ، فطائر مماثلة مع التعيين/التحميل الزائد ، وحتى تشمل الخطأ:
نسخة الكود كما يلي:
var err = new error () ؛
console.log (خطأ erractionof) ؛ // حقيقي
err = 'sofish' ؛
console.log (err) ؛ // 'sofish'
4. أنواع مرجع JavaScript
هذه نقطة صعبة في هذه المقالة. بالمقارنة مع الأنواع الأساسية ، يمكن للمراجع إضافة خصائص وطرق لهم ؛ المراجع هي قيم مماثلة هي مرجع ، حيث تُعين قيمة نوع المرجع إلى متغير ، وتشير إلى نفس القيمة المخزنة في ذاكرة الكومة. يمكن أن تكون المتغيرات (الخصائص) محمولة ، لكن النسخ سيكون أمرًا مثيرًا للاهتمام للغاية ، وسوف نتحدث عنه بالتفصيل لاحقًا.
1. إضافة الخصائص والأساليب
سنرى في الكود التالي أن على افتراض أننا لن نقوم بالإبلاغ عن خطأ في مهمة مماثلة أساسية ، ولكن سيكون غير صالح عند الجلب:
نسخة الكود كما يلي:
var arr = [1،2،3] ؛
arr.hello = 'World' ؛
console.log (arr.hello) ؛ // 'عالم'
var str = 'sofish' ؛
str.hello = 'World' ؛
console.log (str.hello) ؛ // غير محدد
2. تشغيل الإشارة إلى قيم النوع
نظرًا لأن النوع المرجعي يتم تخزينه في ذاكرة المكدس هو مرجع ، عندما نشير إلى نفس القيمة الأصلية ، ستؤثر العملية على القيمة على جميع المراجع ؛ مثال هنا هو أن إعادة التعيين (وليس عملية مباشرة على القيمة) ستعيد إنشاء كائن ولن يغير القيمة الأصلية. على سبيل المثال:
نسخة الكود كما يلي:
var arr = [1،2،3] ، sofish = arr ؛
sofish.push ('Hello World') ؛
console.log (arr) ؛ // [1 ، 2 ، 3 ، "Hello World"]
// نوع غير سامي
sofish = ['ليس سمكة'] ؛ // عندما يتغير Sofish بالمثل ، لن يتم تغيير القيمة الأصلية
console.log (arr) ؛ // [1 ، 2 ، 3 ، 'hello world']
3. نسخ قيم النوع المرجعي
ستؤثر العمليات على القيمة الأصلية على جميع المراجع ، والتي ليست بالضرورة ما نريد. في بعض الأحيان نحتاج إلى نسخ كائن جديد تمامًا دون التأثير على المراجع الأخرى عند التشغيل. بشكل عام ، هناك عدد قليل من العمليات المحددة مثل التاريخ / الوظيفة / regexp ... ، وذلك أساسًا لأن الصفيف والكائن لهما عناصر وسمات إضافية ، إلخ. لذا فإن ما نحتاج إلى فهمه هو كيفية نسخ كائنات الصفيف والكائن.
3.1 نسخ المصفوفات
في كائن الصفيف ، توجد طريقة الشريحة لإعادة صفيف تم اعتراضها ، وفي مرشح ES5 ، وما إلى ذلك ، قم أيضًا بإرجاع مجموعة جديدة ، لذلك قد نستخدم هذه الطريقة لنسخها.
نسخة الكود كما يلي:
var arr = [1 ، 2 ، 3] ؛
var sofish = arr.slice () ؛
// لن تؤثر التشغيل على المصفوفات الجديدة على الصفيف الأصلي
sofish.push ('Hello World') ؛
console.log (arr) ؛ // [1 ، 2 ، 3]
3.2 نسخ الأشياء
في نسخ الصفيف ، نستخدم طريقة الشريحة. في الواقع ، بالنسبة للمصفوفة والكائن ، يمكننا استخدام ... في حلقة لاجتياز وتعيين القيم للنسخ.
نسخة الكود كما يلي:
var obj = {name: 'sofish'} ، sofish = {} ، p ؛
لـ (p في OBJ) sofish [p] = obj [p] ؛
// التشغيل على الكائنات الجديدة لن تؤثر على القيمة الأصلية
sofish.say = function () {} ؛
console.log (OBJ) ؛ // {name: 'sofish'}
3.3 الظل/نسخة عميقة
مثل العملية أعلاه ، هذا ما نسميه في كثير من الأحيان نسخة الظل. ومع ذلك ، يمكن أن يكون لكل من الصفيف والكائن طبقات متعددة (الأبعاد). نسخ مثل هذا يأخذ فقط في الاعتبار قيمة الطبقة العليا. لا يزال الصفيف والكائن في القيم المحتملة يشيران إلى الكائن الأصلي. على سبيل المثال:
نسخة الكود كما يلي:
var arr = [1 ، {bio: 'not a fish'}] ، sofish = [] ، p ؛
لـ (p in arr) {
sofish [p] = arr [p] ؛
}
// العمليات على الكائنات "القط" الواردة في "Sofish" تؤثر على القيمة الأصلية
Sofish [1] .bio = 'hackable' ؛
console.log (arr) ؛ // [1 ، cat: {bio: '' hackable '}]
فكيف تفعل ذلك؟ دعونا نستخدم وظيفة نسخة () لحل هذه المشكلة:
نسخة الكود كما يلي:
/* انسخ الكائن
* param: OBJ {JavaScript Object} كائن أصلي
* param: isdeep {boolean} نسخة عميقة
* return: {JavaScript Object} إرجاع كائن جديد
*/
نسخة وظيفة (OBJ ، isdeep) {
var ret = obj.slice؟ []: {} ، p ، prop ؛
// استخدم مع وظيفة IS
if (! isdeep && is (obj ، 'array')) return obj.slice () ؛
لـ (P في OBJ) {
إذا (! obj.hasownproperty (p)).
prop = obj [p] ؛
ret [p] = (is (prop ، 'object') || is (prop ، 'array'))؟
نسخة (دعامة ، isdeep): Prop ؛
}
العودة
}
وبهذه الطريقة ، يمكننا نسخ صفيف أو كائن من خلال وظيفة النسخ (OBJ ، ISDeep). يمكنك اختباره:
نسخة الكود كما يلي:
var arr = [1 ، {bio: 'not a fish'}] ؛
var sofish = copy (arr) ؛
// نسخة ضحلة لا تؤثر على القيمة الأصلية لتشغيل الطبقة الأولى ، ولكنها تؤثر على الطبقة الثانية
sofish.push ('cat') ؛
console.log (arr) ؛ // [1 ، {bio: 'not a fish'}]
Sofish [1] .bio = 'hello world' ؛
console.log (arr) // [1 ، {Bio: 'Hello World'}]
// لن تؤثر النسخة العميقة على القيمة الأصلية
sofish = نسخة (arr ، 1) ؛
Sofish [1] .bio = 'foo أو bar' ؛
console.log (arr) ؛ // [1 ، {Bio: 'Hello World'}]
هذا كل شيء. يجب أن تفهم بشكل أساسي النقاط الأكثر صعوبة حول الأنواع. بالطبع ، النسخ المتماثل هو النقطة الأكثر إثارة للقلق. بالإضافة إلى الصفيف والكائن الذي يتطلب غالبًا التشغيل ، هناك أيضًا تكرار للتاريخ/الوظيفة/regexp.