Сериализация объекта JavaScript в строку JSON
У меня есть этот прототип JavaScript:
Utils.MyClass1 = function(id, member) {
this.id = id;
this.member = member;
}
и я создаю новый объект:
var myobject = new MyClass1("5678999", "text");
Если я сделаю:
console.log(JSON.stringify(myobject));
результат:
{"id":"5678999", "member":"text"}
но мне нужно, чтобы тип объектов был включен в строку JSON, например:
"MyClass1": { "id":"5678999", "member":"text"}
Есть ли быстрый способ сделать это с помощью фреймворка или что-то? Или мне нужно реализовать метод toJson()
в классе и сделать это вручную?
Ответы
Ответ 1
var myobject = new MyClass1("5678999", "text");
var dto = { MyClass1: myobject };
console.log(JSON.stringify(dto));
РЕДАКТИРОВАТЬ:
JSON.stringify
приведёт в соответствие все "свойства" вашего класса. Если вы хотите сохранить только некоторые из них, вы можете указать их индивидуально, например так:
var dto = { MyClass1: {
property1: myobject.property1,
property2: myobject.property2
}};
Ответ 2
Это просто JSON? Вы можете stringify()
JSON:
var obj = {
cons: [[String, 'some', 'somemore']],
func: function(param, param2){
param2.some = 'bla';
}
};
var text = JSON.stringify(obj);
И снова анализируем обратно в JSON с помощью parse()
:
var myVar = JSON.parse(text);
Если у вас есть функции в объекте, используйте это для сериализации:
function objToString(obj, ndeep) {
switch(typeof obj){
case "string": return '"'+obj+'"';
case "function": return obj.name || obj.toString();
case "object":
var indent = Array(ndeep||1).join('\t'), isArray = Array.isArray(obj);
return ('{['[+isArray] + Object.keys(obj).map(function(key){
return '\n\t' + indent +(isArray?'': key + ': ' )+ objToString(obj[key], (ndeep||1)+1);
}).join(',') + '\n' + indent + '}]'[+isArray]).replace(/[\s\t\n]+(?=(?:[^\'"]*[\'"][^\'"]*[\'"])*[^\'"]*$)/g,'');
default: return obj.toString();
}
}
Примеры:
Сериализация:
var text = objToString(obj); //To Serialize Object
Результат:
"{cons:[[String,"some","somemore"]],func:function(param,param2){param2.some='bla';}}"
Deserialize:
Var myObj = eval('('+text+')');//To UnSerialize
Результат:
Object {cons: Array[1], func: function, spoof: function}
Ответ 3
Ну, тип элемента не стандартно сериализуется, поэтому вы должны добавить его вручную. Например
var myobject = new MyClass1("5678999", "text");
var toJSONobject = { objectType: myobject.constructor, objectProperties: myobject };
console.log(JSON.stringify(toJSONobject));
Удачи!
edit: изменил типof на правильный .constructor. См. https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor для получения дополнительной информации о свойстве конструктора для объектов.
Ответ 4
Это может быть полезно.
http://nanodeath.github.com/HydrateJS/
https://github.com/nanodeath/HydrateJS
Используйте hydrate.stringify
для сериализации объекта и hydrate.parse
для десериализации.
Ответ 5
Вы можете использовать именованную функцию в конструкторе.
MyClass1 = function foo(id, member) {
this.id = id;
this.member = member;
}
var myobject = new MyClass1("5678999", "text");
console.log( myobject.constructor );
//function foo(id, member) {
// this.id = id;
// this.member = member;
//}
Вы можете использовать регулярное выражение для анализа "foo" из myobject.constructor и использовать его для получения имени.
Ответ 6
Ниже приведен другой способ, с помощью которого мы можем использовать данные JSON с функцией JSON.stringify()
var Utils = {};
Utils.MyClass1 = function (id, member) {
this.id = id;
this.member = member;
}
var myobject = { MyClass1: new Utils.MyClass1("5678999", "text") };
alert(JSON.stringify(myobject));
Ответ 7
function ArrayToObject( arr ) {
var obj = {};
for (var i = 0; i < arr.length; ++i){
var name = arr[i].name;
var value = arr[i].value;
obj[name] = arr[i].value;
}
return obj;
}
var form_data = $('#my_form').serializeArray();
form_data = ArrayToObject( form_data );
form_data.action = event.target.id;
form_data.target = event.target.dataset.event;
console.log( form_data );
$.post("/api/v1/control/", form_data, function( response ){
console.log(response);
}).done(function( response ) {
$('#message_box').html('SUCCESS');
})
.fail(function( ) { $('#message_box').html('FAIL'); })
.always(function( ) { /*$('#message_box').html('SUCCESS');*/ });
Ответ 8
Я решил свою проблему таким образом, но не лучшим образом, но интересно поделиться:
Я изменил непосредственно библиотеку json2.js(напротив лучших практик...), изменил метод JSON.stringify() и в функции str(), когда читает объект, который я сначала ставил typeof:
// Otherwise, iterate through all of the keys in the object.
// I have introduced speechModify variable.
var speechModify = false;
if(value.classname) {
partial.push('"' + value.classname + '":{');
speechModify = true;
}
Это только для добавления атрибута classname в мои классы. И после итерации добавляет следующее предложение:
if(speechModify)
partial.push("}");
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
v = v.replace("{,","{");
v = v.replace(",}", "}");
Ответ 9
У меня были некоторые проблемы с использованием вышеупомянутых решений с объектом типа "ассоциативный массив". Кажется, что эти решения сохраняют значения, но они не сохраняют фактические имена объектов, с которыми связаны эти значения, что может вызвать некоторые проблемы. Поэтому я собрал следующие функции, которые я использую вместо:
function flattenAssocArr(object) {
if(typeof object == "object") {
var keys = [];
keys[0] = "ASSOCARR";
keys.push(...Object.keys(object));
var outArr = [];
outArr[0] = keys;
for(var i = 1; i < keys.length; i++) {
outArr[i] = flattenAssocArr(object[keys[i]])
}
return outArr;
} else {
return object;
}
}
function expandAssocArr(object) {
if(typeof object !== "object")
return object;
var keys = object[0];
var newObj = new Object();
if(keys[0] === "ASSOCARR") {
for(var i = 1; i < keys.length; i++) {
newObj[keys[i]] = expandAssocArr(object[i])
}
}
return newObj;
}
Обратите внимание, что их нельзя использовать с любым произвольным объектом - в основном он создает новый массив, хранит ключи как элемент 0 с данными, следующими за ним. Поэтому, если вы попытаетесь загрузить массив, который не создан с этими функциями, имеющими элемент 0 в качестве списка ключей, результаты могут быть... интересными :)
Я использую это так:
var objAsString = JSON.stringify(flattenAssocArr(globalDataset));
var strAsObject = expandAssocArr(JSON.parse(objAsString));