2013-08-14 3 views
0

У меня есть конструктор, который я создал, который имеет метод, который модифицирует кучу локальных переменных. Моя проблема в том, что метод может вызвать некоторую ошибку, поэтому, когда возникает ошибка, я хочу восстановить область до ее предыдущего состояния. Очевидно, я мог бы создать кучу временных переменных, а затем просто назначить их переменным, которые фактически использует конструктор, но это не совсем оптимальное решение. Я хочу знать, есть ли способ изменить переменные из метода и восстановить их до состояния, которое они были до того, как метод был вызван в случае ошибки.Отменить изменения в области конструктора при ошибке

+0

Таким образом, вы хотите создать резервную копию некоторых переменных, но сохранение исходных значений «не оптимально». Как вы предлагаете восстановить, если вы не создали резервную копию в первую очередь? –

+0

«но это не оптимальное решение». Вы имеете в виду, что это не оптимально, потому что * вы должны сделать разматывание стека? Если да, не используйте JavaScript (или большинство языков, если на то пошло). Если вы пишете для браузера, не стесняйтесь использовать один из многих языков программирования 'call/cc' на стороне браузера, которые не существуют. В противном случае просто используйте LISP. –

+0

Хороший случай для шаблона Memento :) –

ответ

3

Помимо глобального охвата, нет реального способа взаимодействия с областями в JavaScript. Тем не менее вы можете создавать объекты, которые действуют как области.

demo

function Scope(data){ 
    this.data = data; 
    this.stages = []; 
    this.save(data); 
} 

Scope.prototype.save = function(){ 
    var oldData = JSON.parse(JSON.stringify(this.data)); 
    this.stages.push(oldData); 
} 

Scope.prototype.undo = function(){ 
    var lastData = this.stages.pop(); 
    this.data = lastData; 
} 

Затем мы можем создать область с некоторыми данными.

var scope = new Scope({name: "John"}); 

Теперь у нас есть странная функция с очень предпочтительным отношением к людям по имени Пол.

function myFunction(data) { 
    if (data.name === "John") { 
    data.name = "Paul"; 
    throw new Error("I don't like John!"); 
    } 
} 

Затем мы можем позвонить нашей функции в попытке/уловить.

try { 
    myFunction(scope.data); 
} 
catch (e) { 
    // scope.data is {name: "Paul"} 
    scope.undo(); 
    // scope.data is {name: "John"} 
} 
2

использование стек,

например.

var Stack = new Array(); 

doModification(10,''); 

function doModification(A,B){ 
    Stack.push(A); 
    Stack.push(B); 

    // after modifying, 
    try{ 
    A= 10; 
    if(B == 0) throw new Error("Divide by Zero Exception."); 
    B= A/B; 
    } 
    catch(e){ 
    // if exception then restore original vars 
    B = Stack.pop(); 
    A = Stack.pop(); 
    alert(e.description); 
    } 

    // else if error doesn't come then, clear the stack 
    Stack = []; 

} 
+0

Просто, чтобы вы знали, '10/0' не выдает ошибку. Это [приводит к 'Infinity'] (http://jsfiddle.net/4T5EJ/). – FakeRainBrigand

+0

@fakeRainBrigand - он будет кидать - «делить на нулевое исключение» – sourcecode

+0

На некоторых языках, но не на JavaScript, кроме, может быть, на старых браузерах. [Пример] (http://jsfiddle.net/4T5EJ/). Firefox и Chrome дают Infinity. – FakeRainBrigand

Смежные вопросы