javascript - لغة - شرح جافا سكريبت




نسخ الصفيف حسب القيمة في JavaScript (14)

أنا شخصيا أعتقد Array.from هو الحل أكثر قابلية للقراءة. بالمناسبة ، فقط حذار من دعم المتصفح.

//clone
let x = [1,2,3];
let y = Array.from(x);

//deep clone
let clone = arr => Array.from(arr,item => Array.isArray(item) ? clone(item) : item);
let x = [1,[],[[]]];
let y = clone(x);

عند نسخ مصفوفة في JavaScript إلى مصفوفة أخرى:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

أدركت أن arr2 يشير إلى نفس الصفيف كـ arr1 ، بدلاً من صفيف مستقل جديد. كيف يمكنني نسخ المصفوفة للحصول على صفيفين مستقلين؟


إذا كنت تريد إنشاء نسخة جديدة من كائن أو مصفوفة ، يجب عليك نسخ خصائص الكائن أو عناصر الصفيف بشكل صريح ، على سبيل المثال:

var arr1 = ['a','b','c'];
var arr2 = [];

for (var i=0; i < arr1.length; i++) {
   arr2[i] = arr1[i];
}

يمكنك البحث عن مزيد من المعلومات على Google عن القيم البدائية الثابتة ومراجع الكائنات القابلة للتغيير.


إضافة إلى حل array.slice () ؛ كن على علم أنه إذا كان لديك صفائف فرعية متعددة الصفوف سيتم نسخها عن طريق المراجع. ما يمكنك القيام به هو تكرار كل شريحة فرعية على حدة

var arr = [[1,1,1],[2,2,2],[3,3,3]];
var arr2 = arr.slice();

arr2[0][1] = 55;
console.log(arr2[0][1]);
console.log(arr[0][1]);

function arrCpy(arrSrc, arrDis){
 for(elm in arrSrc){
  arrDis.push(arrSrc[elm].slice());
}
}

var arr3=[];
arrCpy(arr,arr3);

arr3[1][1] = 77;

console.log(arr3[1][1]);
console.log(arr[1][1]);

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


استخدم هذا:

var newArray = oldArray.slice();

بشكل أساسي ، تقوم عملية slice() باستنساخ الصفيف وتقوم بإرجاع المرجع إلى الصفيف الجديد. لاحظ أيضًا أن:

للمراجع ، السلاسل والأرقام (وليس الكائن الفعلي) ، تنسخ مراجع كائن الشريحة إلى الصفيف الجديد. يشير كلا المصفوفة الأصلية والجديدة إلى نفس الكائن. إذا تغير كائن مرجعي ، فستكون التغييرات مرئية لكل من المصفوفات الجديدة والأصلية.

تكون الأوليات مثل الأوتار والأرقام غير قابلة للتغيير ، لذا من المستحيل إجراء تغييرات على السلسلة أو الرقم.


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

قم بإضافة التعليمة البرمجية التالية في ملف JavaScript الخاص بك:

Object.prototype.clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (i in this) {
        if (i == 'clone') 
            continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } 
        else 
            newObj[i] = this[i]
    } return newObj;
};

واستخدامها ببساطة

var arr1 = ['val_1','val_2','val_3'];
var arr2 = arr1.clone()

سوف تعمل.


جعل نسخة من مجموعة / كائن متعدد الأبعاد:

function deepCopy(obj) {
   if (Object.prototype.toString.call(obj) === '[object Array]') {
      var out = [], i = 0, len = obj.length;
      for ( ; i < len; i++ ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   if (typeof obj === 'object') {
      var out = {}, i;
      for ( i in obj ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   return obj;
}

شكرا لجيمس بادولسي لهذه المهمة.

المصدر: Here


في حالتي الخاصة ، احتجت إلى التأكد من أن المصفوفة بقيت سليمة حتى نجحت في ذلك:

// Empty array
arr1.length = 0;
// Add items from source array to target array
for (var i = 0; i < arr2.length; i++) {
    arr1.push(arr2[i]);
}

فيما يلي بعض الطرق الأخرى للنسخ:

const array = [1,2,3,4];

const arrayCopy1 = Object.values(array);
const arrayCopy2 = Object.assign([], array);
const arrayCopy3 = array.map(i => i);
const arrayCopy4 = Array.of(...array );


لا حاجة jQuery ... مثال على العمل

var arr2 = arr1.slice()

هذا ينسخ المصفوفة من نقطة البداية 0 حتى نهاية الصفيف.

من المهم ملاحظة أنها ستعمل كما هو متوقع للأنواع البدائية (السلسلة ، العدد ، إلخ) ، وأيضاً لشرح السلوك المتوقع لأنواع المراجع ...

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


من ES2015 ،

var arr2 = [...arr1];

هناك Array.from المقدمة حديثا ، ولكن لسوء الحظ ، حتى وقت كتابة هذه السطور ، لا يتم دعمها إلا على إصدارات Firefox الأخيرة (32 أو أعلى). يمكن استخدامه ببساطة على النحو التالي:

var arr1 = [1, 2, 3];
console.log(Array.from(arr1)); // Logs: [1, 2, 3]

المرجع: Here

أو يمكن استخدام Array.prototype.map مع وظيفة هوية:

function identity(param)
{
    return param;
}

var arr1 = [1, 2, 3],
    clone = arr1.map(identity);

المرجع: Here


وهنا البديل:

var arr1=['a', 'b', 'c'];
var arr2=eval(arr1.toSource());
arr2.push('d');
console.log('arr1: '+arr1+'\narr2: '+arr2);
/*
 *  arr1: a,b,c
 *  arr2: a,b,c,d
 */

يمكنك أيضًا استخدام مشغل توزيع ES6 لنسخ Array

var arr=[2,3,4,5];
var copyArr=[...arr];

يمكنك استخدام حيزات المصفوفة ... لنسخ المصفوفات.

const itemsCopy = [...items];

أيضًا إذا كنت تريد إنشاء مصفوفة جديدة مع كون المجموعة الحالية جزءًا منها:

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];

يتم دعم فروق المصفوفة الآن في جميع المتصفحات الرئيسية ، ولكن إذا كنت بحاجة إلى دعم أقدم ، استخدم typescript أو babel وترجمت إلى ES5.

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…





arrays