تم تطوير نسخة JavaScript Deep من قبل المبتدئين وحتى ذوي الخبرة ، وغالبًا ما تواجه مشاكل ولا يمكنهم فهم نسخة JavaScript Deep بشكل جيد للغاية.
Deepclone؟
عكس النسخة العميقة هو نسخة ضحلة. يتم الخلط بين العديد من المبتدئين عندما يتصلون بهذا الشعور.
لماذا تستخدم نسخة عميقة؟
في كثير من الحالات ، نحتاج إلى تعيين قيم للمتغيرات وتعيين قيمة لعنوان الذاكرة. ومع ذلك ، عند تعيين نوع قيمة مرجعية ، فإننا نشارك فقط منطقة ذاكرة ، مما يؤدي إلى الحفاظ على الاتساق مع القيمة السابقة عند التعيين.
انظر مثال محدد
// قم بتعيين كائن لاختبار var test = {a: 'a' ، b: 'b'} ؛ // envision test to test2 // في هذا الوقت ، يشارك اختبار واختبار كائن الذاكرة نفسه ، وهو النسخة الضحلة من var test2 = test ؛ test2.a = 'a2' ؛ test.a === 'a2' // صحيح.توضيح:
هذه فكرة جيدة لفهم سبب تأثير بيانات القيمة المرجعية على بعضها البعض.
ينجز
لتنفيذ وظيفة نسخة عميقة ، علينا أن نتحدث عن النوع العددي من JavaScript.
تحديد نوع JavaScript
هناك الأنواع الأساسية التالية في JavaScript
اكتب الوصف
يحتوي النوع غير المحدد المحدد على قيمة واحدة فقط غير محددة ، وهي القيمة عند عدم تعيين المتغير.
نوع nullnull يحتوي أيضًا على قيمة واحدة فقط ، وهو مرجع كائن فارغ
BooleAnboolean له قيمتان: صحيح وكاذب
سلسلة أنها تمثل معلومات النص
الرقم يمثل المعلومات الرقمية
الكائن هي مجموعة غير مرتبة من سلسلة من الخصائص ، بما في ذلك وظيفة الوظيفة ومصفوفة الصفيف
من المستحيل الحكم على الوظيفة والمصفوفة باستخدام typeof. هنا نستخدم comple.prototype.toString طريقة.
[بشكل افتراضي ، سيرث كل كائن من الكائن إلى طريقة ToString (). إذا لم تتم كتابة هذه الطريقة (محظورة) بنفس طريقة الاسم على الكائن نفسه أو النموذج الأولي العلوي الأقرب ، فسيتم استدعاء طريقة TOSTRING () للكائن ويمثل نوع السلسلة هنا نوع كائن] [1]
نوع الوظيفة (obj) {var toString = Object.prototype.toString ؛ var map = {'[object boolean]' ':' boolean '،' [number] ':' number '،' [Object string] ':' string '،' [object function] ':' function '،' [object array] ':' Artry '،' [Object date] ':' date '،' [object regexp] " 'NULL' ، '[Object Object]': 'Object'} ؛ خريطة العودة [tostring.call (obj)] ؛}تنفيذ DeepClone
بالنسبة للقيم الرقمية لأنواع القيمة غير المرجعية ، يتم تعيين القيمة مباشرة ، وبالنسبة لأنواع القيمة المشار إليها (كائن) ، تحتاج إلى اجتيازها مرة أخرى وتعيينها بشكل متكرر.
وظيفة deepclone (البيانات) {var t = type (data) ، o ، i ، ni ؛ if (t === 'array') {o = [] ؛ } آخر if (t === 'Object') {o = {} ؛ } آخر {return data ؛ } if (t === 'array') {for (i = 0 ، ni = data.length ؛ i <ni ؛ i ++) {o.push (deepclone (data [i])) ؛ } إرجاع o ؛ } آخر إذا (t === 'Object') {for (i in data) {o [i] = deepclone (data [i]) ؛ } إرجاع o ؛ }}هناك نقطة هنا يجب على الجميع الانتباه إليها. بالنسبة لأنواع الوظائف ، هل يقوم المدون بتعيين القيم مباشرة أو يشارك قيمة الذاكرة. وذلك لأن الوظائف تدور حول إكمال وظائف معينة ، مع قيمة الإدخال وقيمة الإرجاع ، وبالنسبة للخدمات ذات المستوى العلوي ، فهي أكثر حول إكمال وظائف الأعمال ، وليس هناك حاجة لنسخ الوظيفة بعمق.
ولكن كيفية نسخ نوع الوظيفة؟
في الواقع ، فكر المدون فقط في استخدام جديد لتشغيله ، ولكن سيتم تنفيذ الوظيفة مرة واحدة ، ولا أجرؤ على تخيل ما ستكون عليه نتيجة التنفيذ! س (□) يا! ليس لدي أي أفكار جيدة حتى الآن ، من فضلك أعطني إرشادات!
في هذه المرحلة ، تم الانتهاء من النسخة العميقة تقريبًا ، لكن بعض الناس يعتقدون أنه لماذا لم يتم تنفيذ النسخة الضحلة؟
نسخة ضحلة؟
بالنسبة للنسخ الضحلة ، يمكن فهمها على أنها تشغيل منطقة ذاكرة مشتركة واحدة فقط! سيكون هناك خطر هنا! (..*)
إذا قمت بتشغيل هذه البيانات المشتركة مباشرة دون التحكم فيها ، فغالبًا ما تحدث استثناءات البيانات وتغييرها بواسطة أجزاء أخرى. لذلك ، يجب ألا تدير مصدر البيانات مباشرة ، وتغليف بعض الطرق لأداء عمليات Curd على البيانات.
ربما يكون الأمر نفسه تقريبًا هنا ، ولكن كواجهة أمامية ، لا يعتبر JavaScript نفسه فحسب ، بل أيضًا DOM ، المتصفح ، إلخ.
نوع العنصر
دعونا نلقي نظرة على الكود التالي ، ماذا سيتم إرجاعه في النتيجة؟
Object.prototype.toString.call(document.getElementsByTagName('div')[0])
الجواب هو [كائن htmldivelement]
في بعض الأحيان عندما يتم حفظ عنصر DOM وإذا قمت بنسخه عن طريق الخطأ ، فإن وظيفة النسخ العميقة أعلاه تفتقر إلى الحكم على عنصر العنصر. للحكم على عنصر العنصر ، استخدم مثيل الحكم. لأنه بالنسبة لعلامات مختلفة ، ستعيد ToString المنشئ المقابل لعلامات مختلفة.
نوع الوظيفة (obj) {var toString = Object.prototype.toString ؛ var map = {'[object boolean]' ':' boolean '،' [number] ':' number '،' [Object string] ':' string '،' [object function] ':' function '،' [object array] ':' Artry '،' [Object date] ':' date '،' [object regexp] " 'NULL' ، '[Object Object]': 'Object'} ؛ if (OBJ electionof element) {return 'element' ؛ } خريطة الإرجاع [tostring.call (obj)] ؛}طرق أخرى؟
تنفيذ jQuery
للحصول على تفاصيل ، يرجى الاطلاع على https: //github.com/jquery/jqu ...
تنفيذ السطح
للحصول على التفاصيل ، يرجى الاطلاع على https: //github.com/jashkenas/...
تنفيذ Lodash
للحصول على التفاصيل ، يرجى الاطلاع على https: //github.com/lodash/lod ...
تنفيذ JSON
يمكنك إدراك نسخة عميقة من خلال مرور JSON.Stringify أولاً ، ثم Json.Parse. ومع ذلك ، فإن نوع البيانات يدعم فقط الأنواع الرقمية الأساسية.
var obj = {a: 'a' ، b: function () {console.log ('b')}} // عندما يتم ترشيح الوظيفة. json.stringify (obj) // "{" a ":" a "}"ملخص
هنا نلخص النسخة العميقة هنا تقريبًا وكيفية تنفيذ نسخة عميقة. في سيناريوهات مختلفة ، من الضروري تحديد ما إذا كانت هناك حاجة إلى نسخة عميقة بناءً على سيناريو العمل.