2009-12-08 3 views
1

Например, у меня есть два массива ArrayCollection - firstAC и secondAC. Если я делаю secondAC = firstAC, и чем я вношу изменения в secondAC (предположительно помещаю функцию filter на него), он каким-то образом распространяется на firstAC, кто-нибудь скажет мне, почему это происходит в Flex или ActionScript 3?Изменения одной переменной распространяются на другую

Что делать, если я хочу, чтобы secondAC получал все данные от firstAC, но затем, когда я вношу изменения в secondAC, он не отображается в firstAC?

Thanxs связка для ответов! Ladislav

ответ

0

В ECMAScript языках (AS1-3, JavaScript и др.), При использовании

var foo = //some value which is not a String or a Number 

то, что вы действительно говорят «Foo теперь указывает на тот же объект, как тот другой переменной.» Это означает, что в этой ситуации, оба массива будут иметь то же значение:

var foo:Array = [ 1, 2, 3 ]; 
foo = bar; 
bar.push(4); 
trace(foo); // 1, 2, 3, 4 

Это также работает для функций:

var foo:Array = [ 1, 2, 3 ]; 
adder(foo); 
function adder(bar:Array):void { 
    bar.push(4); 
} 

trace(foo); // 1, 2, 3, 4 

и он даже работает с XML:

var xml:XML = <root><foo/></root>; 
var bar:XML = xml; 
bar.children()[ 0 ][email protected] = 1; 
trace(xml.toXMLString()); // <root><foo bar="1"/></root> 

Этот называется «передача по ссылке» вместо «передача по значению» или «передача по копии». Это означает, что каждый раз, когда объект ссылается, каждая переменная указывает на тот же объект.

Существует множество способов обойти это, и большинство из них зависит от вашего контекста. Для массивов моим любимым является Array.concat(), который возвращает литеральный клон массива. Это означает, что все, что я делаю с возвращенным значением, никак не повлияет на оригинал. Однако, если я имею дело с XML, я сделаю что-то вроде: var xml2:XML = XML(xml.toXMLString());.

В вашем случае, я бы на самом деле рекомендуем использовать:

var secondAC:ArrayCollection = new ArrayCollection(firstAC.source.concat()); 

Это основные преимущества не только быть быстрее (это зависит от скомпилированного кода вместо Flex SDK кода, и это также не первый создать экземпляр нового массива, а затем повторно заполнить его), но он также имеет явное преимущество в более ранних версиях SDK Flex 3 - он полностью обратно совместим.

+0

Большое спасибо за этот ответ, очень приятные примеры ... thanx для вашего времени! Ladislav – Ladislav

5

Когда вы пишете secondAC = firstAC, вы просто указываете, что secondAC и firstAC являются ссылками на одну и ту же коллекцию массивов.

Что вы хотите, так это клонировать первую коллекцию (как, например, копировать все элементы по одному).

Вы должны быть в состоянии сделать это с чем-то вроде:

secondAC = new ArrayCollection(); 
secondAC.addAll(firstAC); 
+0

Большое спасибо за объяснение того, что происходит – Ladislav

1

я не имею ни малейшего представления о Flex или Actionscript, но выглядит как firstAC и secondAC указывают на тот же массив, поэтому это ожидается.

Что нужно сделать, так это просто создать другой массив, скопировать элементы, и они будут двумя реальными разными объектами.

1

Вместо secondAC = firstAC вы можете попробовать secondAC.addAll(firstAC).

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