可以創建一個事務數組,記錄對對象所做的每個更改並記錄有關更改的足夠數據,以便可以將其撤消。這並不是一項微不足道的工作。例如,它與字處理程序或電子表格中的撤消功能有點類似。如果您記錄了正確的信息級別並將其保存在一個數組中,則應該可以撤消所有更改。這不是火箭科學,但它是一些編寫和測試的代碼。
正如在評論中提到的,這裏提出的一個更大的問題是關於一個單一的25MB對象,必須通過一個函數來操作。我個人懷疑是否可以將數據分解成更小的部分,並且能夠使用更小的副本來不必編寫整個撤消操作。
此外,值得考慮的是,您是否可以預先足夠的操作來提前知道在修改對象之前代碼是否會失敗。例如,我之前使用的代碼與修改對象的代碼運行所有相同的邏輯,但實際上並未修改對象。這使您可以運行整個操作的預執行,從而確定在實際修改對象之前是否有任何操作失敗。寫得恰當的話,你可以使用相同的代碼進行飛行前的實際修改,只需傳入一個額外的標誌。這是多麼可行取決於修改操作的確切性質,您還沒有透露。
下面是處理特定對象屬性更改的代碼示例。這可以擴展到包括數組操作。
工作演示:http://jsfiddle.net/jfriend00/ohqL0p06/
代碼:
function TransactionSummary() {
this.transactions = [];
}
TransactionSummary.prototype = {
deleteProperty: function(parent, property) {
this.rememberTransaction(parent, property, "delete", parent[property]);
delete parent[property];
},
modifyProperty: function(parent, property, newVal) {
this.rememberTransaction(parent, property, "modify", parent[property]);
parent[property] = newVal;
},
addProperty: function(parent, property, newVal) {
this.rememberTransaction(parent, property, "add");
parent[property] = newVal;
},
rememberTransaction: function(parent, property, type, oldVal) {
this.transactions.push({parent: parent, property: property, type: type, oldVal: oldVal});
},
undoTransactions: function() {
var t;
while (this.transactions.length) {
t = this.transactions.pop();
switch(t.type) {
case "delete":
case "modify":
t.parent[t.property] = t.oldVal;
break;
case "add":
delete parent[property];
break;
}
}
}
}
「寫少勿多」! –
這裏我關心的是爲什麼你有一個25mb的JavaScript對象... – taxicala
這聽起來像你需要讓你的檢查返回原先的對象,然後跟進你的檢查,實際上修改對象。 –