JavaScript中能否不使用显式return从其他函数触发外层函数返回
问题解答
JavaScript/TypeScript 没有原生支持让被调用函数直接触发调用方返回的语法,你示例中的 fnc.return() 能力无法通过原生方式实现,但有多种更高抽象的方案可以达成你要的「避免重复编写校验逻辑、无需每个父函数单独写判断返回」的需求。
方案1:高阶函数封装公共校验(最通用,无环境依赖)
把公共校验逻辑抽成高阶函数,所有需要加该校验的业务函数直接用这个高阶函数包装即可,完全消除重复校验代码:
// 抽离公共校验逻辑的高阶函数 const withCheck = (failReturn) => (fn) => { return (...args) => { // 这里写你原本的公共校验逻辑 const checkPass = /* 你的校验条件 */ false; if (!checkPass) { // 校验不通过直接返回指定结果,不会执行后续业务逻辑 return failReturn; } // 校验通过才执行原业务函数 return fn(...args); } } // 业务函数a,完全不用写校验逻辑,指定校验失败返回值为"hi" const a = withCheck("hi")(function(){ // 原来a的后续业务逻辑 console.log('a的业务逻辑执行'); return 'a的正常返回'; }); // 业务函数aa,同样不用写校验,指定校验失败返回值为false const aa = withCheck(false)(function(){ // 原来aa的后续业务逻辑 console.log('aa的业务逻辑执行'); return 'aa的正常返回'; }); // 调用效果和你伪代码预期完全一致 a(); // 校验不通过时直接返回"hi",不会执行a内部的业务代码
方案2:装饰器(适合TS/支持装饰器语法的类场景)
如果你的代码是基于类编写的,可以用装饰器实现和高阶函数一样的效果,写法更简洁:
function Check(failReturn: any) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { const checkPass = /* 校验条件 */ false; if (!checkPass) return failReturn; return originalMethod.apply(this, args); } return descriptor; } } class Test { @Check("hi") a() { console.log('a的业务逻辑执行'); return 'a正常返回'; } @Check(false) aa() { console.log('aa的业务逻辑执行'); return 'aa正常返回'; } }
方案3:异常拦截(仅适合校验失败属于异常场景的情况)
如果校验失败属于需要中断流程的异常场景,也可以通过抛出自定义异常+统一捕获的方式实现,这种方式不推荐用于正常业务流程的提前返回,会增加调试成本:
// 自定义校验失败异常 class CheckFailError extends Error { constructor(public returnValue: any) { super('校验失败'); } } // 校验函数,失败直接抛异常 const b = () => { const checkPass = /* 校验条件 */ false; if (!checkPass) throw new CheckFailError("hi"); } const a = () => { b(); // 只要校验失败直接抛异常,后续代码不会执行 console.log('a的业务逻辑执行'); } // 调用时统一捕获,也可以在顶层全局统一处理 try { const res = a(); } catch (e) { if (e instanceof CheckFailError) { const res = e.returnValue; // 拿到提前返回的值 } }
内容的提问来源于stack exchange,提问作者ProtectedVoid
相关产品推荐
相关产品推荐

