Самый простой способ это так же, как вы вырваться из любого вызова функции: выдаст ошибку.
var obj = {
someCondition: false,
a: function() {
return this;
},
b: function() {
if (!this.someCondition) {
var error = new Error("A message");
error.name = "SomeConditionError";
throw error;
}
return this;
},
c: function() {
return this;
}
};
А затем вызовите методы и обработайте ошибку.
try {
obj
.a()
.b() // throws a "SomeConditionError" here
.c();
}
catch (error) {
if (error.name == "SomeConditionError") {
// gracefully handle "SomeConditionError"
}
else {
// rethrow errors you don't know how to handle gracefully
throw error;
}
}
Единственное, чего вы хотите избежать, это using exceptions for flow control.
Если вам нужно вызвать obj.a()
затем obj.b()
, но затем условно назвать obj.c()
то вызывающий код должен справиться с этим:
obj.a().b();
if (someCondition) {
// Assign to "obj" just in case obj.c() returns a different object
obj = obj.c();
}
Он чувствует себя уродливой кода (и это несколько), но сообщает, что любые ошибки, вызванные этими вызовами метода, являются катастрофическими, показывая ошибки остановки. Если у вас есть сложная операция, которая включает в себя несколько вызовов метода на одном объекте или нескольких объектов, считают инкапсулирования, что в «command»:
function DoSomethingCommand(obj) {
this.obj = obj;
}
DoSomethingCommand.prototype = {
constructor: DoSomethingCommand,
execute: function() {
this.obj.a().b();
if (someCondition) {
this.obj = this.obj.c();
}
}
};
С точки зрения вызывающего кода, это только простой вызов execute()
к начинайте очень сложный процесс:
var command = new DoSomethingCommand(obj);
command.execute();
Если вы напишете 'c()', это будет выполнено. То, что вы могли бы сделать, это заменить возвращаемое значение 'b' на' {c: function() {}} ', но это отвратительно. –
@OmarElawady, который выкинул бы ошибку – Mark
Вы не можете выйти из функции, если вы ее запустили. Функция заканчивается в инструкции return или в конце ее тела. –