Как сериализовать и десериализовать объекты Javascript?
Мне нужно сериализовать и десериализовать объекты Javascript для их хранения в БД.
Обратите внимание, что эти объекты содержат функции, поэтому я не могу хранить их как JSON, поэтому я не могу использовать json2.js.
Что представляет собой современное состояние в [de] сериализации javascript-объектов (в javascript, конечно).
Спасибо,
Стюарт
Ответы
Ответ 1
В общем, нет способа (в браузере) сериализовать объекты с прикрепленными к ним функциями, так как каждая функция имеет ссылку на внешнюю область. Если функция ссылается на любую из этих переменных, они больше не будут существовать при десериализации.
Что бы я хотел использовать встроенные функции (или json2.js) JSON.stringify
и JSON.parse
с параметрами replacer
и reviver
. Вот частичный пример того, как он будет работать:
JSON.stringify(yourObject, function(name, value) {
if (value instanceof LatLng) { // Could also check the name if you want
return 'LatLng(' + value.lat() + ',' + value.lng() + ')';
}
else if (...) {
// Some other type that needs custom serialization
}
else {
return value;
}
});
JSON.parse(jsonString, function(name, value) {
if (/^LatLng\(/.test(value)) { // Checking the name would be safer
var match = /LatLng\(([^,]+),([^,]+)\)/.exec(value);
return new LatLng(match[1], match[2]);
}
else if (...) {
...
}
else {
return value;
}
});
Вы можете использовать любой формат сериализации в своих пользовательских типах. Формат LatLng (широта, долгота) - это всего лишь один из способов сделать это. Вы даже можете вернуть объект javascript, который может быть сериализован в JSON изначально.
Ответ 2
Вы не хотите сериализовать логику, такую как функции.
Если вам нужно обновить свои функции логики /js в будущем, вы не (всегда) хотите, чтобы старая логика была загружена обратно с данными, необходимыми. Осторожно.
Ответ 3
используйте gserializer:
http://www.onegeek.com.au/articles/programming/javascript-serialization.php
код в google:
http://code.google.com/p/gserializer/
GSerializer - это библиотека javascript для Сериализация/десериализация javascript объектов в строки и из них, для настойчивость, скажем, в Cookie. В отличие от многие другие реализации, GSerializer также может сериализовать функций и нотации без JSON.
Ответ 4
В Node.js также есть пакет JASON.
Вот пример:
var JASON = require("JASON");
str = JASON.stringify(obj);
obj = JASON.parse(str);
Установите пакет: npm install JASON
.
Ответ 5
Если вы используете версии ES6 Node, вы можете проверить небольшой пакет, который я написал, называемый JSOFF. Это текстовый формат JavaScript; замена для JSON, которая обрабатывает функции.
Это супер крошечный и простой, поэтому Babeljs или Browserify могут быть вашими друзьями.
Установите через: npm install jsoff
или yarn add jsoff
.
Вот пример создания объекта с функциями:
const JSOFF = require('jsoff');
var obj = {
abc: 123,
def: function (a,b) { return a * 2 + b * 3; },
ghi: a => { return a * 2 },
jkl: (a,b) => { return ((d,e) => { return a*d + b*e })(2,4) }
};
var str = JSOFF.stringify(obj);
// str is now:
// '{"abc":123,"def":"function (a,b) { return a * 2 + b * 3; }","ghi":"a => { return a * 2 }","jkl":"(a,b) => { return ((d,e) => { return a*d + b*e })(2,4) }"}');
});
var clone = JSOFF.parse(str);
clone.def(10,5) // 35
clone.ghi(5) // 10
clone.jkl(10,20) // 100
Ответ 6
Я бы не стал сериализовать функции JS из соображений безопасности. Через открытый API всевозможные неприятные вещи могут быть отправлены в базу данных. Что касается десериализации, у меня другой подход. Я смешиваю объекты модели, определенные на стороне клиента, с данными, поступающими от JSON. У меня есть небольшой инструмент для этого, посмотрите на GitHub на khayll/jsonmix.
JsonMix предоставляет своего рода десериализацию от JSON в JavaScript-объекты, в комплекте с функциями.
Это будет выглядеть как-то:
//model definition (just an example)
var LatLng = function() {}
LatLng.prototype.getMapTypeId = function() {
return this.mapTypeId;
}
//deserializing done like this
var result = JSMix(jsonString).withObject(LatLng.prototype, "latLngs").build();
//all items in the latLngs collection have the functions coming from the model
console.log(result.latLngs[5].getMapTypeId());