说我有这个功能(伪代码):
function Foo() {
let varThatRequiresCleanup = //something
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
varThatRequiresCleanup.CleanUp();
return Success;
}
来自C ++和C语言世界,我只想在析构函数中实现清理或使用goto
,但JavaScript都没有。
一旦CleanUp()
返回,我该如何打电话给Foo()
?
是返回的每个CleanUp()
中调用if
的唯一方法吗?
答案 0 :(得分:3)
一种替代方法是对重复代码使用函数:
function Foo() {
let varThatRequiresCleanup = //something
function CleanUpAndReturn(returnValue) {
varThatRequiresCleanup.CleanUp();
return returnValue;
}
if (condition1) { return CleanUpAndReturn(Error1); }
if (condition2) { return CleanUpAndReturn(Error2); }
if (condition3) { return CleanUpAndReturn(Error3); }
//etc.. more ifs and important code.
return CleanUpAndReturn(Success);
}
答案 1 :(得分:2)
在javascript中,您可以在函数(即闭包)中定义和调用函数。
通过这种方式,您可以通过这种方式实现您所需要的:
function Foo() {
let varThatRequiresCleanup = //something
// Define your "actual" Foo logic in an inner function
// where you can define your flow and return logic as
// needed.
function InnerFoo() {
// You can access variables in the Foo closure, like so
console.log(varThatRequiresCleanup);
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
return Success;
}
// Now call your inner function like so
var result = InnerFoo();
// Now you can cleanup resourced in scope of Foo as
// in this way, because this line will be hit
varThatRequiresCleanup.CleanUp();
// Return the result from InnerFoo()
return result;
}
答案 2 :(得分:1)
您可以做一个叫做猴子补丁的事情。
概念取自here。
function foo(){
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
}
var tempFoo = foo;
window.foo = function() {
tempFoo();
//do the cleanup here
CleanUp();
}
答案 3 :(得分:1)
您可以使用try-finally块:
function Foo() {
let varThatRequiresCleanup = //something
try {
if(condition1) {
return Error1;
}
if(condition2) {
return Error2;
}
if(condition3) {
return Error3;
}
//etc.. more ifs and important code.
return Success;
} finally {
varThatRequiresCleanup.CleanUp();
}
}
答案 4 :(得分:0)
您可以使用代理来拦截对方法的调用。
通过将new Proxy
返回给构造函数来工作。然后,我们处理get
调用,然后我们可以首先调用该方法,然后再运行清理。这将使我们只需要在代理内调用一次清除,而不必在方法本身内调用。
class MyClass {
constructor() {
this.varThatRequiresCleanup = null
// Create a reference to `this` so the function below can use it
let $this = this
// A private function this will clean stuff up
// We can't use `this` in this function because it references window
// We will use our reference `$this` instead
function cleanup() {
$this.varThatRequiresCleanup = null
console.log('cleaned up')
}
// Create a proxy that will handle the method calls
return new Proxy(this, {
get: (target, prop, receiver) => {
// Get the called property
let targetValue = Reflect.get(target, prop, receiver)
// Execute the called property
return (...args) => {
let r = targetValue.apply(this, args)
console.log('before varThatRequiresCleanup:', this.varThatRequiresCleanup)
cleanup()
console.log('after varThatRequiresCleanup:', this.varThatRequiresCleanup)
return r
}
}
})
}
Foo() {
this.varThatRequiresCleanup = 'foo'
return 'foo result'
}
Bar() {
this.varThatRequiresCleanup = 'bar'
return 'bar result'
}
}
let c = new MyClass()
console.log('Foo Return Value:', c.Foo())
console.log('-----------')
console.log('Bar Return Value:', c.Bar())