Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Способ сериализации объектов нужен.


Автор: ksnk 25.7.2009, 12:49
Кто может посоветовать быстрый и эффективный способ сериализации объектов в строку и обратно. Объект - достаточно общей структуры, вложенные объекты, перекрестные ссылки... Вот разве что элементов-функций пока не предполагается...

Интересует и не кроссброузерные реализации, для FireFox'а.

Пока остановился на нарытом в Интернетах php-serialize-unserialize для JavaScript. Хотя  на сложноповязанных объектах его не тестировал, но на первый взгляд - то, что надо... 
Есть ли что-нибудь попроще-побыстрее?

Автор: IDVsbruck 25.7.2009, 13:13
По-моему, удобнее чем JSON ничего нет ...
Использовать рекурсивный способ обхода объекта, записывание в строку и отправка. Само собой, о типах приведения должны знать обе стороны.

Автор: ksnk 25.7.2009, 13:45
IDVsbruck, Тут немного другая проблема. Предполагается сохранение-восстановление большого объема данных на JavaScript без предачи ее на сервер. Я полагал, что есть какая-то хитрая фенечка от FireFox, такой-же хитрости как и xpath...

А в принципе, json, конечно, получше PHP-сериалайза, хотя бы по тому, что делать придется только одну операцию, а строка преобразуется уже обычным eval'ом...

Автор: ksnk 25.7.2009, 17:41
json пока не подошел :-(
Нужно уметь сохранять циклические ссылки
Код

var a={x:1,y:2}, b={prev:a, x:1,y:2}; 
      a.follow=b; 
      a.next=a;

Нужно сохранить объект a, так, чтобы при десериализации его возник новый (или старый, если есть ;-) ) объект b и восстановились все ссылки.

В Json такое пока не очень вписывается...


Автор: IDVsbruck 26.7.2009, 00:23
Не скажи ... 
Во-первых, можно назначать свойства не буквально, а через свою функцию, то это как раз создаст некий свой сериалайзер.
Во-вторых можно использовать идентефикаторы, которые, кстати, можно назначать через глобальную для объекта переменную.
Таким образом, объект уже будет выглядеть не как obj = {var1:val1, var2:{a:{x:1,y:2}, b:{prev:a, x:1,y:2}}}, а типа такого: obj = {var1:val1, var2:[{id:0,x:1,y:2}, {id:1,prev:0, x:1,y:2}]}. Несколько универсальных функций сделают всю работу ... думаю, ничего сложного не будет с поиском объектов, назначением идентефикаторов, установкой дополнительных свойств в зависимых объектах.

Автор: youri 26.7.2009, 22:39
а для чего это нужно?
и как насчет связывания объектов через id?

Автор: ksnk 27.7.2009, 00:49
Цитата(youri @  26.7.2009,  22:39 Найти цитируемый пост)
а для чего это нужно?

Есть дополнение для FireFox'а - GreaseMonkey. Оно позволяет "подключить" к любой из заданного диапазона страниц дополнительный JavaScript файл. У этого скрипта, в отличии от обычных скриптов странички, появляется возможность сохранять свои переменные в отдельной, зависимой только от этого скрипта области памяти. Выглядит это как "куки", которые не передаются на сервер и доступны только этому скрипту. При работе скрипта, в случае перезагрузки страницы нужно сохранить-восстановить текущее состояние. Вот для этого и нужна процедура де/сериализации объектов.

Про область применения такого дополнения - смотрите в Гугле. В основном - мелкая автоматизация, украшательство... 

Что такое "привязывание по ID" в таком контексте, осталось мне непонятным smile

Пока разродился такой идеей. Вот такой объект 
Код

var a={hello:'world'}, b={hello:'world'}; 
      a.xx=b; 
      a.next=a;

 будет преобразован вот в такую строку
Код

_REF(1,{hello:'world',xx:{hello:'world'},next:_REF(1)})

где _REF - функция, которая в случае, если есть второй параметр - сохраняет ссылку по индексу из первого параметра и ее выдает, если второго параметра нету - просто выдает ссылку на сохраненный объект.

Примерный алгоритм
- первый проход:
-- пробегаем рекурсивно в глубину объекта и каждому элементу "подвешиваем" дополнительное свойство __saved=true
-- если нам оказывается нужно сериализовать объект с уже установленым в true таким свойством - уcтанавливаем это свойство в инкрементируемый счетчик.

- второй проход нужен только если обнаружены циклические ссылки. Результат первого прохода отбрасывается 
-- опять двигаемся вглубь объекта.
-- если нам оказывается нужно сериализовать объект с уже установленым в число таким свойством и счетчик больше 0 - возвращаем _REF( счетчик, изображение объекта), счетчик делаем отрицательным.
-- если нам оказывается нужно сериализовать объект с уже установленым в число таким свойством и счетчик меньше 0 - возвращаем _REF( счетчик)

-третий проход - углубляемся в объект и выкидываем все свойства __saved.

Алгорим немного идиотичен, во всяком случае записаный на JavaScript он мне не понравился, попробую пооптимизировать... 

Автор: IDVsbruck 27.7.2009, 13:55
youri спросил то, о чем я выше написал ... ссылки указывают не на объекты на их идентефикаторы (посмотри пример).

Автор: ksnk 27.7.2009, 14:21
IDVsbruck, Ну, если так посмотреть, то 1 из выражения _REF(1) в моих измышлениях, тот самый идентификатор и есть... smile Тогда получается, что понял...
В принципе, обычная сериализация в С++ делается в чем-то похожим способом...

задача обрастает новыми подробностями.

Есть комплект объектов, которые создаются при старте скрипта, их сохранять ни в коем случае не надо + есть комплект объектов, которые хранятся в сериализованных строках. Из первого множества ссылок во второе нет, а из второго есть куда угодно... В принципе, можно перечислить и "поименовать" все объекты из первого множества и после этого сохранять и восстанавливать второе, идентификаторы уже будут известны, проблема лишь в том. что от версии к версии количество "стационарных" объектов может меняться... 

Очень не хочется, однако придется, сохранять элементы - функции. Сохранять исходный код функции несложно, тем более, что FireFox дает его "посмотреть" скрипту, однако совершенно некошерно. В случае изменения исходного кода элемента будет большой геморой выловить и расстреляять кусочки от прошлой версии...  Придется, видимо, набор функций-элементов фиксировать и хранить теми-же идентификаторами. Хотя, возможно удастся элементы функции вообще не использовать...

Еще желательно восстанавливать не все объекты, хранящиеся в хранилище, а только нужные. При этом возникает задача подгрузить недостающие "объекты-строки", если на их элементы есть есть ссылки...

Получается сумбурно, да еще и задача все время обрастает деталями... А возможно, я ее непреднамеренно усложняю  smile 

Если будет время, порешаю, чего-нибудь попишу и выложу сюда код...

Автор: youri 27.7.2009, 18:36
Цитата(ksnk @  27.7.2009,  14:21 Найти цитируемый пост)
Получается сумбурно, да еще и задача все время обрастает деталями... А возможно, я ее непреднамеренно усложняю   

вот поэтому я считаю, что нужно описывать задачу с самого верхнего уровня, а не только тот уровень, на котором возникли проблемы ;)

Автор: ksnk 27.7.2009, 18:49
Цитата(youri @  27.7.2009,  18:36 Найти цитируемый пост)
 описывать задачу с самого верхнего уровня

пока идет проектирование. Один из ключевых моментов - сохранение данных между релодами страницы. Какие данные будут сохраняться, как они буду выглядеть пока не очень понятно ;-)

Автор: Itsys 27.7.2009, 19:09
Посмотри на http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_serialize/, вроде они решили данную задачу.

Автор: ksnk 27.7.2009, 21:31
Itsys, Они там с большой колокольни плюют на рекурсивные ссылки. Мне так нельзя smile К тому-же когда я говорил про 
Цитата(ksnk @  25.7.2009,  12:49 Найти цитируемый пост)
 php-serialize-unserialize для JavaScript
 я имел ввиду именно это решение, (ну или его предшественника судя по комментариям в коде)...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)