2017-01-14 19 views
0

В этом коде ... mapObj.fetchTimeObjs НЕ МОЖЕТЕ измениться????!
Как-то mapObj.fetchTimeObjs получает изменилось, когда эта функция выполняется:JavaScript scoping (копирование одного массива в другой)

function clockErasePast(){ 
    var now = new Date().getTime(); 
    var tmpFetchTimeObjs = []; 
    for(var i =0; i<mapObj.fetchTimeObjs.length; i++){ 
     tmpFetchTimeObjs.push(mapObj.fetchTimeObjs[i]); 
     if(mapObj.fetchTimeObjs[i].start < now){tmpFetchTimeObjs[i].start = now;} 
    } 
    return tmpFetchTimeObjs; 
} 

ответ

1

tmpFetchTimeObjs[i] будет содержать только ссылку на mapObj.fetchTimeObjs[i].

Если изменится tmpFetchTimeObjs[i], то mapObj.fetchTimeObjs[i] будет изменен, потому что вы будете иметь только один объект, который имеет два ссылки. И если он изменится с одной ссылки, он будет изменен и на вторую ссылку.

Рассмотрим объект, имеющий две ссылки. Здесь я изменяю объект из одной ссылки и получаю обновление для второй ссылки, потому что они ссылаются на один и тот же объект.

var objA = { name: 'Bob', age: 25}; 
 
var objB = objA; 
 

 
objB.age = 30; 
 

 
console.log(objA.age);

Чтобы получить независимый объект, который нужно создать. Вы можете использовать функцию Object.assign(), которая скопирует любые перечислимые свойства из объекта назначения (первый параметр) и вернет его.

Вы можете создать с

var obj = Object.assign({}, mapObj.fetchTimeObjs[i]); 
tmpFetchTimeObjs.push(obj); 
+0

ok ... так как я могу сделать копию этого ... так что я могу изменить tmp и не испортить оригинал? – rikkitikkitumbo

+0

@rikkitikkitumbo см. Обновление –

+0

ну, безболезненное тестирование со старым дерьмовым ipod (Object.assign, похоже, не работает в более старых версиях сафари). Это единственное решение, которое работает для всего: $ .extend (true, [], mapObj.fetchTimeObjs) .... нашел его здесь: http://stackoverflow.com/questions/7486085/copying-array-by -value-in-javascript – rikkitikkitumbo

1

объекты, которые вы push в новый массив, такие же, как исходный массив имеет, так что если вы мутировать их, что мутация видна обоих массивов. Это то, что принято называть мелкой копией.

Вы можете сделать копию на одном более глубоком уровне, где вы также создадите новые объекты и скопируете свойства исходного объекта (например, start) в эти новые объекты. Это можно легко сделать с Object.assign:

tmpFetchTimeObjs.push(Object.assign({}, mapObj.fetchTimeObjs[i])); 

Если эти объекты сами вложенные объекты, то проблема у вас будет происходить на более глубоких уровнях. Если это проблема, вы должны посмотреть на глубокие решения для клонирования, как описано в этом документе Q&A.

0

Вам необходимо клонировать TimeObjs, так как переменные содержат только ссылку на TimeObjs. Мы не знаем структуру вашего TimeObjs, поэтому, если TimeObjs не содержит других объектов, будет работать Object.assign(), иначе вам может понадобиться метод глубокого клонирования, например jQuery.extend().

+0

yup! $ .extend - это то, что сработало для меня. array.slice() и array.splice (0) не выполнялись: http: // stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript – rikkitikkitumbo

+0

@rikkitikkitumbo Приятно, но $ .extend также будет терпеть неудачу, если в ваших объектах есть частные переменные. –

+0

@rikkitikkitumbo Если у вас есть информация или знания о том, как создать экземпляр 'TimeObjs', вы можете написать собственный клонер, специализирующийся на клонировании' TimeObjs'. Таким образом, вам больше не нужно импортировать 'jQuery'. –

Смежные вопросы