Ortak nesne referanslari iceren nesneyi serialize etmek (JavaScript)

Ceviz Viki, özgür ansiklopedi

Git ve: kullan, ara

JavaScript nesnesini JSON benzeri bir sekilde yazdirir. Ortak kullanilan nesne referanslarini da goz onunde bulundurur.

Ne ise yaradigi hakkinda bir ornek:

var obj = {};
obj.array = [{a:10}, [], true, false, null, undefined, 7, 3.141, "'\"\r\n\t\b\fabc"];
obj.array_tekrar = obj.array;
obj.kendisi = obj;
obj.array_ilk = obj.array[0];
obj.array_ikinci = obj.array[1];
obj.array_ucuncu = obj.array[2];
 
var s = serialize(obj);
var yeni = deserialize(s);
 
alert(yeni == obj); // false
alert(yeni.array[7]); // 3.141
alert(yeni.array == yeni.array_tekrar); // true
alert(yeni.kendisi == yeni); // true
alert(yeni.array_ilk == yeni.array[0]); // true
alert(yeni.array_ikinci == yeni.array[1]); // true
 
alert(s);
/* Ciktisi:
{
"array": [
{
"a": 10
},
[],
true,
false,
null,
undefined,
7,
3.141,
"'\"\r\n\t\b\fabc"
],
"array_tekrar": { _root_: [ "array" ] },
"kendisi": { _root_: [ ] },
"array_ilk": { _root_: [ "array", 0 ] },
"array_ikinci": { _root_: [ "array", 1 ] },
"array_ucuncu": true
}
*/

Ve kod:

//============================================================================//
// JavaScript object de/serialization with shared object references. //
// //
// author: Mehmet Yavuz Selim Soyturk //
// e-mail: Mehmet dot Yavuz dot Selim at gmail dot com //
//============================================================================//
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
// //
//============================================================================//
 
Array.prototype.findIf = function(predicate) {
for(var i in this) {
if (predicate(this[i]))
return i;
}
return -1;
};
Array.prototype.map = function(func) {
var len = this.length;
var result = [];
for (var i=0; i<len; i++) {
result[i] = func(this[i]);
}
return result;
};
Array.prototype.appended = function(value) {
var copy = this.slice(0);
copy[copy.length] = value;
return copy;
};
 
//============================================================================//
// SERIALIZATION //
//============================================================================//
 
function indented(n) {
var s = '';
for(var i=0; i<n; i++) s += ' ';
return s;
}
 
function escape_string(str) {
str = str .replace( new RegExp('\\\\', 'g') , '\\\\' )
.replace( new RegExp('"', 'g') , '\\"' )
.replace( new RegExp('/', 'g') , '\\/' )
.replace( new RegExp('\b', 'g') , '\\b' )
.replace( new RegExp('\f', 'g') , '\\f' )
.replace( new RegExp('\n', 'g') , '\\n' )
.replace( new RegExp('\r', 'g') , '\\r' )
.replace( new RegExp('\t', 'g') , '\\t' );
return str;
}
 
function serializePrimitive(value) {
if (typeof value == 'string')
return '"' + escape_string(value) + '"';
else
return '' + value;
}
 
function serializePrimitiveArray(arr) {
var s = "[ ";
s += arr.map(serializePrimitive).join(', ');
s += " ]";
return s;
}
 
function serializeArray(arr, seen, indices, depth) {
seen[seen.length] = {obj: arr, indices: indices};
 
if (arr.length == 0)
return '[]';
 
var result = '[\n';
for (var i=0; i<arr.length; i++) {
result += indented(depth + 1);
result += serializeAny(arr[i], seen, indices.appended(i), depth + 1);
result += (i == arr.length - 1) ? '' : ', ';
result += '\n';
}
result += indented(depth) + ']';
 
return result;
}
 
function serializeObject(obj, seen, indices, depth) {
seen[seen.length] = {obj: obj, indices: indices};
 
var properties = [];
for (var prop_name in obj) {
if (typeof obj[i] != 'function')
properties[properties.length] = prop_name;
}
 
if (properties.length == 0)
return '{}';
 
var result = '{\n';
for (var i = 0; i < properties.length; i++) {
var prop_name = properties[i];
result += indented(depth+1);
result += '"' + escape_string(prop_name) + '": ';
result += serializeAny(obj[prop_name], seen,
indices.appended(prop_name), depth + 1);
result += (i == properties.length - 1) ? '' : ', ';
result += '\n';
}
result += indented(depth) + '}';
 
return result;
}
 
 
function serializeAny(value, seen, indices, depth) {
var t = typeof(value);
var prevIndex;
 
if (t == 'function') {
throw new Error("Cannot serialize function. Keys from root: " +
serializePrimitiveArray(indices));
}
else if (t != 'object' || value == null) {
return serializePrimitive(value);
}
else if ( (prevIndex = seen.findIf
( function(obj) { return obj.obj == value } )
) >= 0) {
return '{ _root_: ' + serializePrimitiveArray(seen[prevIndex].indices) + ' }';
}
else if (value.constructor == Array) {
return serializeArray(value, seen, indices, depth);
}
else {
return serializeObject(value, seen, indices, depth);
}
};
 
function serialize(obj) {
return serializeAny(obj, [], [], 0);
}
 
 
 
//============================================================================//
// DESERIALIZATION //
//============================================================================//
 
function followIndices(obj, indices) {
for (var i=0; i<indices.length; i++)
obj = obj[indices[i]];
 
return obj;
}
 
function replaceRootRefs(obj, root) {
if (typeof obj != 'object' || obj == null)
return;
 
for (var i in obj) {
var prop = obj[i];
if (typeof prop == 'object' && prop != null) {
if ('_root_' in prop)
obj[i] = followIndices(root, prop._root_);
replaceRootRefs(prop, root);
}
}
}
 
function deserialize(str) {
var obj = eval( '(' + str + ')' );
if (str.indexOf('_root_') < 0)
return obj;
 
replaceRootRefs(obj, obj);
return obj;
}