Tôi không rõ cách serialization/de-serialization được cho là hoạt động trên các đối tượng đã nhập trong JavaScript. Ví dụ, tôi có một đối tượng "MapLayer" có chứa các thành viên và mảng khác nhau. Tôi đã viết (nhưng chưa được kiểm tra) đoạn mã sau để cố gắng serialize nó:Làm theo tuần tự hóa Javascript của các đối tượng đã nhập
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;
}
Câu hỏi của tôi là, làm thế nào là đối tượng kết quả phải được deserialized như một đối tượng MapLayer chứ không phải là một đối tượng chung chung. Và làm thế nào là tất cả các trường hợp Sprite được cho là được deserialized như sprites. Tôi có nên sử dụng "MapLayer mới()" thay vì "{}" không? Hoặc tôi chỉ đơn giản là nghĩa vụ phải bao gồm các nguyên mẫu và tính chất constructor của đối tượng trong serialization? Tôi còn thiếu cái gì nữa không? Tôi đang làm điều này một cách ngu ngốc? Có 2 lý do tôi không sử dụng mã tuần tự hóa/de-serialization chung:
- Tôi muốn tuần tự hóa dữ liệu ô theo định dạng được tối ưu hóa thay vì lưu trữ biểu diễn chuỗi cơ sở cho mỗi ô và có chúng tất cả được phân tách bằng dấu phẩy.
- Tôi không muốn sắp xếp hàng loạt tileet làm đối tượng được tạo thành đối tượng mới trong quá trình hủy tuần tự hóa, mà là tham chiếu đến đối tượng hiện có. Có thể sử dụng mã như tôi đã đề xuất ở trên không?
Chỉnh sửa: Xin lỗi vì thiếu thuật ngữ thích hợp; JavaScript là một trong những ngôn ngữ ít chuyên môn của tôi. Những gì tôi có nghĩa là khi tôi nói "Typed Object" là một đối tượng với một constructor. Trong ví dụ này, constructor của tôi là:
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;
}
Chỉnh sửa 2: Lấy mã từ Šime Vidas' câu trả lời, tôi đã thêm một đối tượng liên quan được gọi là "thiết bị":
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);
Bây giờ câu hỏi là cách tốt nhất để kết hợp các đối tượng phụ thuộc như vậy, bởi vì một lần nữa, "kiểu" (nguyên mẫu?) của đối tượng bị mất bởi JSON. Thay vì chạy hàm khởi tạo, tại sao chúng ta không đơn giản thay đổi tuần tự hóa và các hàm de-serialize để đảm bảo rằng đối tượng chỉ cần được xây dựng một lần như thế này thay vì tạo và sao chép?
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);
};
Sửa 3: Một vấn đề tôi đã là JSON dường như không làm việc trong IE9. Tôi đang sử dụng tập tin này kiểm tra:
<html>
<head>
<title>Script test</title>
<script language="javascript">
console.log(JSON);
</script>
</head>
</html>
Và giao diện điều khiển đầu ra:
SCRIPT5009: 'JSON' is undefined
test.html, line 5 character 1
Sửa 4: Để khắc phục sự cố JSON tôi phải bao gồm thẻ DOCTYPE đúng ngay từ đầu.
Đối tượng được nhập là gì? –
Một đối tượng với một hàm tạo khác với "Đối tượng". Tôi không biết phải gọi nó là gì. – BlueMonkMN
Ah, bạn có nghĩa là các đối tượng là trường hợp của các nhà xây dựng của riêng bạn ('MapLayer',' Sprite', v.v.) ... –