Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Сериализация объектов (совместимая с eval) [обсуждение] (Denis Usenko, оценка: 4)
Author Message
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Mon Sep 15, 2008 10:31 pm (написано за 3 минуты 8 секунд)
   Post subject: Сериализация объектов (совместимая с eval) [обсуждение]
Reply with quote

Это старая версия кода, новая тут (forum.dklab.ru/viewtopic.php?t=32576)!!!


Собственно код:
Code (JavaScript): скопировать код в буфер обмена
toLiteral = Object.prototype.toSource ?

function (val) {
    return val.toSource()
} :

function (val) {
    var esc = {'"' : '\\"', '\\': '\\\\', '\/': '\/', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r'};
    var cnv = function (val) {
        switch (val.constructor) {
        case String:
            //return '"' + val.replace(/["\\\/\b\f\n\r]/g, function(a){ return esc[a] }) + '"';
            return '"' + val.replace(/[\x22\\\/\b\f\n\r]/g, function(a){ return esc[a] }) + '"';
        case Array:
            var a = [], i = val.length;
            while(i--) a[i] = cnv(val[i]);
            return '[' +  a.join(',') + ']';
        case Object:
            var a = [], i = 0, k;
            for(k in val) a[i++] = (/^[a-zA-Z_][\w_]*$/.test(k) ? k : cnv(k)) + ':' + cnv(val[k]);
            return '{' +  a.join(',') + '}';
        case Date:
            return 'new Date(' + (val-0) + ')';
        default:
            return val;
        };
    };
    return '(' + cnv(val) + ')';
};

//
//
//

obj = {
    a: 1,
    b: new Date,
    c: [
        NaN,
        '"\\\/\b\f\n\r\t',
        {
            n: true,
            m: {
                //y: function(){ return 123 },
                z: 1
            }
        }
    ],
    d: "another string",
    e: /^[A-Za-z\_]\w+\s*:\s*.*?$/

};

_ = function (v) { document.writeln(v) };

_(toLiteral(obj));

obj2 = eval(toLiteral(obj));

_('---------------------');

_(obj2.b)
ЗЫ. Подсветка сбоит в регекспах на 22h символе
Правка: ключи не оборачивались в кавычки
Back to top
View user's profile Send private message
Миша Спларов
Участник форума



Joined: 17 Nov 2003
Posts: 821
Карма: 65
   поощрить/наказать

Location: Россия, Москва

PostPosted: Tue Jan 13, 2009 7:00 am (спустя 3 месяца 27 дней 8 часов 28 минут; написано за 30 секунд)
   Post subject:
Reply with quote

А где unserialize? :-)
И чем JSON (www.json.org/json2.js) не нравится?
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Tue Jan 13, 2009 12:14 pm (спустя 5 часов 13 минут; написано за 49 секунд)
   Post subject:
Reply with quote

Denis Usenko,
не плохая работа! +1! :)

А насчет JSON, согласен с Михаилом. ;)

P.S. А что не в Складе тема?
Back to top
View user's profile Send private message Send e-mail
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Wed Jan 14, 2009 3:46 am (спустя 15 часов 32 минуты; написано за 5 минут 3 секунды)
   Post subject:
Reply with quote

Миша Спларов wrote:
А где unserialize? И чем JSON не нравится?
Есть хорошее правило -- можешь не писать код -- не пиши ))
toSource -- это ровно то, что мне надо, а поскольку рано или поздно все браузеры (или почти все) будут поддерживать toSource, я с удовольствием потру большую часть кода toLiteral )). А unserialize -- это eval ))
Александр Михалицын wrote:
А что не в Складе тема?
Ну, на всякий, вдруг будет обсуждение. Можно второй пост туда скопировать.
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Wed Jan 14, 2009 12:05 pm (спустя 8 часов 18 минут)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «Сериализация объектов (совместимая с eval)»,
расположенную в форуме Склад готовых решений :: JavaScript (14 Января 2009, 15:05).
Back to top
View user's profile Send private message Send e-mail
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Mon Feb 02, 2009 10:08 am (спустя 18 дней 22 часа 2 минуты; написано за 10 секунд)
   Post subject:
Reply with quote

Denis Usenko,
кстати, для отладки было бы полезно, чтобы
ваш "серилизатор" еще и оформлял код по нормальному.
Тоесть код:
Code (JavaScript): скопировать код в буфер обмена
var some_array = [
   {
      '1': 1,
      '2': function() { return this[1]; }
   },
   function() { alert("Hello, World"); }
]
Был на выходе не кучей букв, а чем-то вроде:
Code (any language): скопировать код в буфер обмена
[
   {
      '1': 1,
      '2': <...>
   },
   <...>
]
Back to top
View user's profile Send private message Send e-mail
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Mon Feb 02, 2009 12:32 pm (спустя 2 часа 24 минуты; написано за 1 минуту 5 секунд)
   Post subject:
Reply with quote

Code (JavaScript): скопировать код в буфер обмена
case Array:
            var a = [], i = val.length;
            while(i--) a[i] = cnv(val[i]);
            return '[' +  a.join(',') + ']';
Denis Usenko,
а ведь строковые ключи бывают и у массивов!
Судя по выше процитированому коду, на это вы не расчитывали!
Code (JavaScript): скопировать код в буфер обмена
var a = new Array();
a["hello"] = 1;
alert(a.hello);
Back to top
View user's profile Send private message Send e-mail
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Mon Feb 02, 2009 5:26 pm (спустя 4 часа 53 минуты; написано за 1 минуту 47 секунд)
   Post subject:
Reply with quote

Такс. Вот то что понаписал про отступы -- реализовал! (А вто про массивы пока не стал, ибо там не так просто
как с хешами -- ведь запись ['key': value] не допускается.)
Code (JavaScript): скопировать код в буфер обмена
String.prototype.repeat = function(num) {
   var result = '';
   for (var i=0; i<num; i++) {
      result += this;
  }
  return result;
}

serialize = Object.prototype.toSource ?

function (val) {
    return val.toSource()
} :

function (val, detCR) {

    var rgstr = [], esc = {'\b':'b','\f':'f','\n':'n','\r':'r','\t':'t'};
    var cnv = function (val, spacers_num) {
        if( detCR && typeof val == 'object' ) {
            if( rgstr.indexOf(val) > 0 )
                return " #CR# ";
            else
                rgstr.push(val);
        };
        var spacer = "   ".repeat(spacers_num);
        var spacer_s = "   ".repeat(spacers_num-1);
        switch (val ? val.constructor : 0) {
        case String:
            return "'" + val.replace(/[\x27\\\/\b\f\n\r]/g, function(a){ return '\\' + (esc[a] || a) }) + "'";
        case Array:
            var a = [], i = val.length;
            while(i--) a[i] = cnv(val[i], spacers_num+1);
            var str = '[\n'+spacer +  a.join(',\n'+spacer) + '\n'+spacer_s+']';
            return str;
        case Date:
            return 'new Date(' + (val-0) + ')';
        case RegExp:
            return val;
        default:
            if( val === null || typeof val != 'object' ) return val;
        case Object:
            var a = [], i = 0, k;
            for(k in val) a[i++] = cnv(k, spacers_num+1) + ': ' + cnv(val[k], spacers_num+1);
            var str = '{\n'+spacer +  a.join(',\n'+spacer) + '\n'+spacer_s+'}';
            return str;
        case Function:
            return val.toString().split('\n').join(' ');
        };
    };

    return '' + cnv(val, 1) + '';
};

if(!Array.prototype.indexOf)
Array.prototype.indexOf = function (v, start) {
    for(var i = start < 0 ? this.length + start : start || 0, l = this.length; i < l; i++)
        if(v === this[i]) return i;
    return -1
}

//
//
//

function MyConstructor() {
    this.prop1 = 'val 1';
    this.prop2 = 'val 2';
};

hash = { 'key1': 1 };
hash.key1 = hash;

testObject = {
    'cr': hash,
    'new AnyObject': new MyConstructor,
    'new Function': new Function,
    'new Date': new Date,
    'new Array': new Array(1,2,3),
    'new String': new String(" "),
    'literal number': 123456,
    'literal string': " ",
    'literal object': { a: 1, b: 2, c: [1,2,3], d: {x: true, y: false} },
    'literal array': [1,2,3,4,5],
    'literal function': function(){ return 123 },
    'NaN': NaN,
    'Infinity': Infinity,
    'true': true,
    'false': false,
    'null': null,
    'undefined': undefined,
    'undefined value': window.qwpeoi,
    'some regexp': /^[A-Za-z\_]\w+\s*:\s*.*?$/,
    'any \' key \" name \n': 'any value = \'"\\\/\b\f\n\r\t',
    'complex hash': {
        n: true,
        m: {
            y: function(){ return 123 },
            z: 1
        },
        a: [1,2,3, {d:1,b:2}]
    }
};

alert(serialize(testObject, 'detected cr' ));
Надеюсь, вы Denis Usenko, будете дальше модернизировать мой исходный код, в нем исправлены только отступы, больше я ничего не менял.
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Mon Feb 02, 2009 6:07 pm (спустя 40 минут; написано за 42 секунды)
   Post subject:
Reply with quote

Code (JavaScript): скопировать код в буфер обмена
String.prototype.repeat = function(num) {
    return (new Array(num+1)).join(this.valueOf());
}
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Tue Feb 03, 2009 10:59 am (спустя 16 часов 51 минуту; написано за 29 секунд)
   Post subject:
Reply with quote

WingedFox,
угу. Дык я расширение это, на коленке писал... ;) (Особенно не раздумывал.)
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Tue Feb 03, 2009 11:12 am (спустя 13 минут; написано за 9 секунд)
   Post subject:
Reply with quote

FYI
Code (JavaScript): скопировать код в буфер обмена
var parentObj = new function () {
   this.a = 'b';
}

var childObjConstr = function () {
}

childObjConstr.prototype = parentObj;

var childObj = new childObjConstr;


document.writeln(serialize(childObj, 'detected cr' ));
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Tue Feb 03, 2009 12:07 pm (спустя 55 минут; написано за 4 секунды)
   Post subject:
Reply with quote

WingedFox,
и?
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Tue Feb 03, 2009 12:10 pm (спустя 2 минуты; написано за 28 секунд)
   Post subject:
Reply with quote

Александр Михалицын
Некорректное поведение.
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Tue Feb 03, 2009 12:17 pm (спустя 6 минут; написано за 16 секунд)
   Post subject:
Reply with quote

WingedFox,
что некорректно? То что {}?
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Tue Feb 03, 2009 12:41 pm (спустя 24 минуты; написано за 11 секунд)
   Post subject:
Reply with quote

То что внутри - то и некорректно.
Back to top
View user's profile Send private message
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Wed Feb 04, 2009 8:40 am (спустя 19 часов 58 минут; написано за 2 минуты 35 секунд)
   Post subject:
Reply with quote

Александр Михалицын, по пунктам:
1) оформление кода лесенкой -- этого не делает ФФокс, это не нужно для сохранениея данных в куках, window.name и всяческих сторэйджах. Для того чтобы "просто посмотреть" юзаю совсем простую функу, но Ваш вариант пожалуй возьму на вооружение ))
2) юзер-свойства объектов-массивов, объектов-строк (var str = new String) и прочих не наблюдаются в выводе toSource ФФох'а. А значит и мы не будем ))

Функа по возможности старается имитировать поведение нативной toSource.
Например, можно было бы сериализовать так чтобы при eval восстанавливались все цикличиские ссылки, но Ффокс сериализует так что при таком eval будет exception, поэтому и здесь сделано так же.

правка: (toSource естественно, а не (toLiteral)

Last edited by Denis Usenko on Thu Feb 05, 2009 8:13 am; edited 2 times in total
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Wed Feb 04, 2009 10:13 am (спустя 1 час 33 минуты; написано за 2 минуты 33 секунды)
   Post subject:
Reply with quote

Denis Usenko,
а зачем все делать как в FF, он что эталон? ;) (Например я его запускаю только для проверки совместимости моего кода с ним
не более... Торможной он уж очень...)
Я вот вашу функцию воспринимаю именно как средство отладки (а значит аккуратного вывода элементов) + как средство сериализации...
Back to top
View user's profile Send private message Send e-mail
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Thu Feb 05, 2009 8:16 am (спустя 22 часа 2 минуты; написано за 4 секунды)
   Post subject:
Reply with quote

Александр Михалицын, может эталон и громкое слово, но ничего более эталонного пока вроде нет )) Я тоже не юзаю ФФ как основной браузер, но каким местом от должно быть связано с разработкой? toSource -- стандартная функция экма-скрипт, и можно надеятся что она таки будет реализована во всех основных движках. (да, и выше описка, должно быть toSource))
Quote:
Я вот вашу функцию воспринимаю именно как средство отладки (а значит аккуратного вывода элементов) + как средство сериализации...
И очень хорошо, для этого код и выкладывается, я не против любого его использования. Но все таки мне думается, что дебаг вывод и сериализация немного разные вещи.

PS. Сейчас только заметил -- функа объявлена без var, поправил. И конечно в предыдущем посту я имел ввиду toSource ))
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Thu Feb 05, 2009 10:37 am (спустя 2 часа 21 минуту; написано за 1 минуту 18 секунд)
   Post subject:
Reply with quote

Quote:
дебаг вывод и сериализация немного разные вещи.
Согласен. Но ничто не мешает вам сделать два варианта функции. =)
Тем более основу (отступы) я реализовал), осталось разве что с массивами разобраться (кстати для обоих случаев), а то например массив
Code (JavaScript): скопировать код в буфер обмена
var c = [];
c["some"] = 1;
будет некорректно сериализован.
Back to top
View user's profile Send private message Send e-mail
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Thu Feb 05, 2009 3:29 pm (спустя 4 часа 51 минуту; написано за 1 минуту 57 секунд)
   Post subject:
Reply with quote

Александр Михалицын wrote:
Code (JavaScript): скопировать код в буфер обмена
var c = [];
c["some"] = 1;
alert(c.length);
это я к тому, что операция [] это нифига не доступ к элементу массива, а к свойству объекта. И это свойство объекта нифига элементом массива не становится.
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Thu Feb 05, 2009 3:40 pm (спустя 10 минут; написано за 2 минуты 2 секунды)
   Post subject:
Reply with quote

dimagolov,
ммм. Ну да впринципе, тогда наверно и сериализовать эти свойства объекта ненадо. ;)
Back to top
View user's profile Send private message Send e-mail
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Tue Feb 24, 2009 1:33 pm (спустя 18 дней 21 час 52 минуты; написано за 40 секунд)
   Post subject:
Reply with quote

Александр Михалицын, да мне очень понравилось смотреть дамп Вашим вариантом с отступами ))
Поэтому поковырял еще немного функу, добавил возможность html-эскейпить вывод, и параметр максимальной глубины, для дампа нативных объектов, типа winodw, event и т.д. Всяческие фишечки и идеи всяческих фишечек приветствуются.
Code (JavaScript): скопировать код в буфер обмена
(function (arr, str) {

   arr.indexOf || (arr.indexOf = function (v, start) {
       for(var i = start < 0 ? this.length + start : start || 0, l = this.length; i < l; i++)
           if(v === this[i]) return i;
       return -1
   });

    str.x = function (n) {
        //
        return Array(n > 0 ? n + 1 : 0).join(this)
    };

    var _e = document.createElement('pre');

    str.toHTML = function () {
        _e.innerHTML = '*';
        _e.firstChild.nodeValue = this;
        return _e.innerHTML
    };

})(Array.prototype, String.prototype);

/*

function dump (value, detCR, indent, htmlescape, maxDepth) {

    indent = typeof indent == 'number' ? ' '.x(indent || 4) : indent || ' '.x(4);

    var rgstr = [],
        esc = {'\b':'b','\f':'f','\n':'n','\r':'r','\t':'t'},
        cnv = function (value, prevIndent, depth) {

            if( detCR && value !== null && typeof value == 'object' ) {
                if( rgstr.indexOf(value) > 0 )
                    return " #CR# ";
                else
                    rgstr.push(value);
            };

            var stopRecurs = depth > maxDepth,
                currIndent = prevIndent+indent;

            switch (value ? value.constructor : 0) {
            case String:
                return "'" + value.replace(/[\x27\\\/\b\f\n\r]/g, function(a){ return '\\' + (esc[a] || a) }) + "'";
            case Function:
                return (''+value).replace(/^|\r?\n/g, '\r\n'+currIndent);
            case Array:
                if( stopRecurs ) return '[folded array: '+value+']';
                var a = [], i = value.length;
                while(i--) a[i] = cnv(value[i], currIndent, depth+1);
                var str = '[\r\n' + currIndent + a.join(',\r\n' + currIndent) + '\r\n' + prevIndent + ']';
                return str;
            case Date:
                return 'new Date(' + (+value) + ')';
            case RegExp:
                return value;
            default:
                if( value === null || typeof value != 'object' ) return value;
            case Object:
                if( stopRecurs ) return '[folded object: '+value+']';
                var a = [], i = 0, k;
                for(k in value) a[i++] = cnv(k, currIndent, depth+1) + ': ' + cnv(value[k], currIndent, depth+1);
                var str = '{\r\n' + currIndent + a.join(',\r\n' + currIndent) + '\r\n' + prevIndent+'}';
                return str;
            }
        },
        result = ''+cnv(value, '', 0);

    return htmlescape ? result.toHTML() : result
};

/*


Last edited by Denis Usenko on Wed Feb 25, 2009 8:27 pm; edited 3 times in total
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 82
   поощрить/наказать


PostPosted: Tue Feb 24, 2009 4:25 pm (спустя 2 часа 52 минуты; написано за 47 секунд)
   Post subject:
Reply with quote

Denis Usenko wrote:
да мне очень понравилось смотреть дамп Вашим вариантом с отступами ))
,
Спасибо, старался. =) (Дык тогда можно и кнопочку соответствующую нажать. =))

А вообще, мне понравилась новая версия... [+]
Back to top
View user's profile Send private message Send e-mail
Denis Usenko
Участник форума



Joined: 06 Feb 2006
Posts: 54
Карма: 13
   поощрить/наказать


PostPosted: Wed Feb 25, 2009 8:25 pm (спустя 1 день 3 часа 59 минут; написано за 34 секунды)
   Post subject:
Reply with quote

Внес пару изменений, поправил свой предыдущий пост.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML