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

Сериализация объектов (совместимая с eval) (Denis Usenko, оценка: 2)
Author Message
Александр Михалицын
Модератор



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


PostPosted: Tue Jan 13, 2009 6:17 am ()
   Post subject:
Reply with quote


М

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



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


PostPosted: Tue Jan 13, 2009 6:17 am (спустя 1 секунду; написано за 1 минуту 40 секунд)
   Post subject: Сериализация объектов (совместимая с eval)
Reply with quote

Неверно сериализовались объекты с конструктором отличным от Object (например new (function(){}))
Ключи всегда надо брать в кавычки, мсие очень капризный.
Добавлена проверка на циклические ссылки, для этого надо указать второй параметр (любое значение приводимое к true). Однако в деле может быть проще брать вызов serialize в try/catch.
Для работы требуется поддержка indexOf у Array.
Функа конечно отличается от Firefox'ного toSource, но вполне годится для тех задач для которых создана (сериализовать простой объект для сохранения в куках/сторэджах или для посылки аяксом)
Code (JavaScript): скопировать код в буфер обмена
var 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) {

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

        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]);
            return '[' +  a.join(',') + ']';
        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) + ':' + cnv(val[k]);
            return '{' +  a.join(',') + '}';
        };
    };

    return '(' + cnv(val) + ')';
};
Тест:
Code (JavaScript): скопировать код в буфер обмена
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}]
    }
};

document.writeln(serialize(testObject, 'detected cr' ));
правка: добавлен var для serialize.

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



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


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

Обсуждение (forum.dklab.ru/viewtopic.php?t=30997)
Back to top
View user's profile Send private message Send e-mail
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