2011-12-28 18 views
8

JavaScript'teki yazılan nesnelerde nasıl serileştirme/serileştirme işleminin nasıl yapılması gerektiği açık değil. Örneğin, çeşitli üyeleri ve dizileri içeren bir "MapLayer" nesnesine sahibim. Aşağıdaki kod serialize girişiminde yazılır (ama henüz test değil) var:Javascript Yazılan Nesnelerin Serileştirilmesi

MapLayer.prototype.serialize = function() { 
    var result = "{tileset:tilesets." + tilesets.getTilesetName(this.tileset) + ",columns:" + this.columns + ",rows:" + this.rows + 
    ",offsetX:" + this.offsetX + ",offsetY:" + this.offsetY + ",currentX:" + this.currentX + ",currentY:" + this.currentY + 
    ",scrollRateX:" + this.scrollRateX + ",scrollRateY:" + this.scrollRateY + ",virtualColumns:" + this.virtualColumns + ",virtualRows:" + this.virtualRows + 
    ",tiles:\"" + this.encodeTileData2() + "\""; 
    for(key in this) 
    { 
     if(this[key] instanceof Sprite) 
     result += "," + key + ":" + this[key].serialize(); 
    } 
    return result; 
} 

Sorum şu, sözde çıkan nesne MapLayer nesnesi olarak yerine jenerik Nesne olarak seriden almak için nasıl. Ve tüm Sprite örneklerinin sprite olarak serpiştirilmesi gerekiyor. "{}" Yerine "yeni MapLayer()" kullanmalı mıyım? Yoksa sadece serileştirme işleminde nesnenin prototip ve yapıcı özelliklerini eklemem gerekiyor mu? Kaybettiğim başka bir şey var mı? Bunu aptalca bir şekilde yapıyorum?

  1. Doğrusu her bir parça için bir üs-10 dize temsilini saklamak daha optimize edilmiş bir biçimde çini verilerini seri istiyor ve onlara sahip: Orada jenerik seri/de-seri kodu kullanarak değilim 2 nedenlerdir hepsi virgülle ayrılmış.
  2. Döşemeyi, serileştirme sırasında değil, varolan bir nesneye başvuru olarak yeni bir nesne olarak oluşturulmuş bir nesne olarak serileştirmek istemiyorum. Yukarıda önerdiğim gibi kod kullanmak mümkün mü?

Düzenleme: Uygun terminolojiden yoksun olmam; JavaScript benim daha az uzmanlık dillerinden biridir. "Yazılan Nesne" dediğimde ne demek istediğim, kurucuya sahip bir nesnedir. Bu örnekte, benim yapıcısı geçerli:

function MapLayer(map, tileset, columns, rows, virtualColumns, virtualRows, offsetX, offsetY, scrollRateX, scrollRateY, priority, tileData) { 
    this.map = map; 
    this.tileset = tileset; 
    this.columns = columns; 
    this.rows = rows; 
    this.offsetX = offsetX; 
    this.offsetY = offsetY; 
    this.currentX = offsetX; 
    this.currentY = offsetY; 
    this.scrollRateX = scrollRateX; 
    this.scrollRateY = scrollRateY; 
    if(tileData.length < columns * rows * 2) 
     this.tiles = DecodeData1(tileData); 
    else 
     this.tiles = DecodeData2(tileData); 
    this.virtualColumns = virtualColumns ? virtualColumns : columns; 
    this.virtualRows = virtualRows ? virtualRows : rows; 
} 

Düzenleme 2:

function Device(description, memory) { 
    this.description = description; 
    this.memory = memory; 
} 

function Person(name, sex, age, devices) { 
    this.name = name; 
    this.sex = sex; 
    this.age = age; 
    this.devices = devices; 
} 

Person.deserialize = function (input) { 
    var obj = JSON.parse(input); 
    return new Person(obj.name, obj.sex, obj.age, obj.devices); 
}; 

var device = new Device('Blackberry', 64); 
var device2 = new Device('Playstation 3', 600000); 
var person = new Person('John', 'male', 25, [device, device2]); 

var string = JSON.stringify(person); 
console.log(string); 

var person2 = Person.deserialize(string); 
console.log(person2); 
console.log(person2 instanceof Person); 

Şimdi soru: Šime Vidas' cevabını kodu alarak, ben "Aygıt" olarak adlandırılan ilgili nesne eklemiş Bu tür bağımlı nesneleri en iyi nasıl birleştirebiliriz, çünkü bir kez daha nesnenin "türü" (prototip?) JSON tarafından kaybedilir. Kurucuyu çalıştırmak yerine, neden sadece seri hale getirilmeyi ve serileştirme işlevlerini, nesnenin yalnızca oluşturulup kopyalanmak yerine bir kez oluşturulmasını sağlamak için değiştirmiyoruz?

Person.prototype.serialize = function() { 
    var obj = this; 
    return '({ ' + Object.getOwnPropertyNames(this).map(function (key) { 
     var value = obj[key]; 
     if (typeof value === 'string') { value = '"' + value + '"'; } 
     return key + ': ' + value; 
    }).join(', ') + ',"__proto__":Person.prototype})'; 
}; 

Person.deserialize = function (input) { 
    return eval(input); 
}; 

Düzenleme 3: ben başka sorun JSON IE9 çalışmak görünmüyor olmasıdır.

<html> 
<head> 
<title>Script test</title> 
<script language="javascript"> 
console.log(JSON); 
</script> 
</head> 
</html> 

Ve konsol çıktıları:

SCRIPT5009: 'JSON' is undefined 
test.html, line 5 character 1 

Düzenleme 4: Başta da doğru DOCTYPE etiketi içermelidir JSON Sorunu gidermek için bu test dosyası kullanıyorum.

Başlangıç ​​için
+1

Yazılan Nesne Nedir? –

+0

"Object" dışında bir kurucuya sahip bir nesne. Ne dediğimi bilmiyorum. – BlueMonkMN

+0

Ah, kendi kurucular ('MapLayer',' Sprite' vb.) Örnekleri olan nesneler anlamında ... –

cevap

8

, buraya özel seri/seriyi kaldırma basit bir örnek:

function Person(name, sex, age) { 
    this.name = name; 
    this.sex = sex; 
    this.age = age; 
} 

Person.prototype.serialize = function() { 
    var obj = this; 
    return '{ ' + Object.getOwnPropertyNames(this).map(function (key) { 
     var value = obj[key]; 
     if (typeof value === 'string') { value = '"' + value + '"'; } 
     return '"' + key + '": ' + value; 
    }).join(', ') + ' }'; 
}; 

Person.deserialize = function (input) { 
    var obj = JSON.parse(input); 
    return new Person(obj.name, obj.sex, obj.age); 
}; 

Kullanımı:

İlk olarak, yeni bir örneği nesne oluşturmak: Şimdi

var person = new Person('John', 'male', 25); 

,

: biz Person.prototype.serialize yöntemi kullanılarak bir dizeye o nesne seri Bu kullanacağım bu dizeyi verecektir

: Son olarak

{ "name": "John", "sex": "male", "age": 25 } 

, biz Person.deserialize statik yöntemini kullanarak bu dizeyi serisini: Artık

var person2 = Person.deserialize(string); 

, person2Person bir örneği olup, aynı özellik içeren Orijinal person örneği olarak değerler.

Canlı tanıtım: Artıkhttp://jsfiddle.net/VMqQN/


, Person.deserialize statik yöntem her durumda gerekli iken (dahili olarak JSON.parse kullanır ve yeni bir örneğini başlatmak için Person kurucuya başvuran), Person.prototype.serialize yöntemi Diğer yandan, yalnızca yerleşik JSON.stringify statik yöntem yeterli değilse gereklidir. var string = JSON.stringify(person) Yukarıdaki benim örnekte

işin çok özel bir seri hale mekanizması gerekli değildir, çok halletmek istiyorum. Bakınız: http://jsfiddle.net/VMqQN/1/ Ancak, durumunuz daha karmaşık olduğundan, özel bir serileştirme işlevi tanımlamanız gerekir.

+1

+1. BÜYÜK Örnek. –

+0

Soruyu güncelledik. Neden kurucuyu çağırmak yerine '__proto__' ayarlamıyoruz? – BlueMonkMN

+0

Başka bir sorun, IE'de JSON kullanmaya çalışırsam, "JSON undefined" hatası alırım. – BlueMonkMN

1

ST-JS (http://st-js.org) projesine bakarsanız, sunucu tarafında Java'nızdaki nesne grafiğini oluşturmanıza, JSON'da seri hale getirmenize ve istemci tarafında (Javascript) seri biçimde yazdırabilirsiniz. Yani, nesneler kurucuları kullanılarak başlatılacak ve oluşturulan nesneler üzerinde yöntemleri çağırabilirsiniz.

o JavaScript neredeyse bire-bir dönüştürülür, istemci kodu Java olduğunu yazmalıyım ST-JS kullanın. Sitenin ana sayfasında

AJAX/JSON bölüm nasıl tür bilgileri tutarken bir JSON dizesi ayrıştırmak için seni açıklıyor.

+0

Bence OP, göç etmek için farklı bir çerçeve yerine mevcut kod tabanı için kullanılacak teknikleri soruyordu. –

+0

Evet, bir şekilde haklısınız. İşaret ettiğim sorun, "yazılan" nesnelerin (Edit 2'de olduğu gibi) bir grafiğin jenerik bir şekilde seri hale getirilebilmesi için, "yazılan nesneleriniz" ile ilgili bazı meta verileri saklamanız gerektiğidir. Desperizatörünüz, örneğin "Aygıt" özelliğinin "Kişi" nin bir dizisidir. –

+0

[Kaynaklarımıza] bakarsanız (https://github.com/st-js/st-js/blob/master/generator/src/main/resources/stjs.js) parseJSON işlevi Kolayca çıkarılabilir), basit bir harita olan "typeDescription" adında bir "statik" alan kullanır - çerçevemizin oluşturduğu, ancak bu da manuel olarak oluşturulabilir. –

İlgili konular