Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ассоциативные массивы
 
 автор: Саня   (15.06.2008 в 18:45)   письмо автору
 
 

Есть у меня множество А. В этом множестве состоят общие элементы для всех объектов моего скрипта. Так же у меня есть другие множества (B, C, D...), являющиеся надмножествами множества А. Код выглядит так:
<script>
A1 = {"a": "aa", "b": "bb"};
B1 = A1;
B1["c1"] = "cc1";

buff = "Объект:\r\n";
for ( k in A1 )
  buff += k + ' = ' + A1[k] + '\r\n';
buff += "\r\nМассив:\r\n";

A2 = new Array();
A2["a"] = "aa";
A2["b"] = "bb";
B2 = A2;
B2["c1"] = "cc1";

for ( k in A2 )
  buff += k + ' = ' + A2[k] + '\r\n';

alert(buff);
</script>
При выполнении скрипта видно, что добавление элемента к множествам B1 и B2 приводит к добавлению такого же элемента в множества А1 и А2 соответственно. Такое ощущение, что переменные B1 и B2 всего лишь ссылки на объекты A1 и A2. Чтобы побороть это, я использую такую функцию:
function cloneObj(obj) {
  var ret = {};
  for ( var k in obj )
    ret[k] = obj[k];
  return ret;
}
Но эта практика кажется мне порочной. Может есть что-то, чего я не знаю про объекты и массивы в данном случае?

   
 
 автор: RMW   (15.06.2008 в 22:53)   письмо автору
 
   для: Саня   (15.06.2008 в 18:45)
 

Объекты - ссылочный тип данных, так что B1 = A1 это не копирование объекта а создание
ещё одного идентификатора для того же самого объекта.

">чтобы побороть это, я использую такую функцию:"
Пожалуй копирование свойств это единственный способ.

">Но эта практика кажется мне порочной."
Возможно дело в неправильном подходе и лучше использовать примерно такой стиль:
function Constr()
{
  this.a = 'aa';
  this.b = 'bb';
}

var A1 = new Constr();
var B1 = new Constr();

Constr.prototype.c1 = 'cс1'

//Здесь свойства a и b являются собственными для каждого объекта (A1, B1)
//Свойство c1 является общим для обоих объектов

   
 
 автор: PAT   (15.06.2008 в 23:02)   письмо автору
 
   для: Саня   (15.06.2008 в 18:45)
 

var A1 = {"a" : "aa", "b" : "bb"}; 

//создаем ПУСТОЙ массив PUST, не определяя ни одного его элемента
var PUST = new Array ();

var B1 = PUST.concat (A);
B1 ["c1"] = "cc1"; 

//Проверяем:
alert (A1 ["c1"]);
//имеем на выходе undefined, что говорит о том, что B1 != A1

   
 
 автор: RMW   (15.06.2008 в 23:57)   письмо автору
 
   для: PAT   (15.06.2008 в 23:02)
 

Интересный способ для копирования массивов используя нативный метод.
Но с объектами такое не прохиляет))))
В вашем примере B1 есть индексированный массив длиной 1, в единственной ячейке
которого лежит опять-таки ссылка на объект A1.

   
 
 автор: Саня   (16.06.2008 в 00:38)   письмо автору
 
   для: RMW   (15.06.2008 в 23:57)
 

Ну почему же? B1 = cloneObj(A1); даёт вполне работоспособные результаты. Тем более объекты у меня тупо ключ -> значение. Ничего более сложного не планируется.

   
 
 автор: RMW   (16.06.2008 в 00:46)   письмо автору
 
   для: Саня   (16.06.2008 в 00:38)
 

Вы же сами говорили, что данная практика вам кажется порочной.
Вот я и предложил альтернативу)))

   
 
 автор: Саня   (16.06.2008 в 00:48)   письмо автору
 
   для: RMW   (16.06.2008 в 00:46)
 

Эх, не хочется мне возиться со всякими конструкторами и объектной моделью... всё, что хочется — обычный ассоциативный массив без этих ссылочных заморочек.

   
 
 автор: Саня   (16.06.2008 в 00:46)   письмо автору
 
   для: PAT   (15.06.2008 в 23:02)
 

> PAT (15.06.2008 в 23:02)
В данном случае получим массив с двумя элементами. Первый — ссылка на объект A1, второй — переменная c1 со значением cc1, что выходит за рамки поставленной задачи.

   
 
 автор: RMW   (16.06.2008 в 00:53)   письмо автору
 
   для: Саня   (16.06.2008 в 00:46)
 

-

   
 
 автор: RMW   (16.06.2008 в 00:58)   письмо автору
 
   для: Саня   (16.06.2008 в 00:46)
 

Нет, Саня, массив содержит одну ячейку.
Не путайте массивы и объекты.

   
 
 автор: Саня   (16.06.2008 в 07:29)   письмо автору
 
   для: RMW   (16.06.2008 в 00:58)
 

<script>
var A1 = {"a" : "aa", "b" : "bb"};  
var PUST = new Array (); 
var B1 = PUST.concat (A1); 
B1 ["c1"] = "cc1";  

buff = "";
for ( k in B1 )
  buff += k + ' = ' + B1[k] + '\r\n';
alert (buff);
/*
0 = [object Object]
c1 = cc1
*/
</script>
И все же два.

   
 
 автор: PAT   (16.06.2008 в 08:46)   письмо автору
 
   для: Саня   (15.06.2008 в 18:45)
 

Помедитировав, предположу:

1. Всякое использование "оператора присваивания" создаст ссылку на существующий объект.
2. Выбранный вами способ (при всей его "некрасивости") не порочен - он единственно возможен в данном случае.
3. Название "ассоциативный массив" для Object object лучше не употреблять :-) Дабы не было "соблазна" использовать методы, применимые только для Array-объектов (как это попытался предложить я ранее - concat)

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования