这是一种非常常见且有用的做法:
// default via value
var un = undefined
var v1 = un || 1
// default via a function call
var myval = () => 1
var v2 = un || myval()
Run Code Online (Sandbox Code Playgroud)
但是在抛出错误时它不起作用(SyntaxError):
var v3 = un || throw new Error('un is not set!')
Run Code Online (Sandbox Code Playgroud)
有没有办法以同样优雅的方式达到同样的效果?这是恕我直言的很多样板代码:
if (!un) {
throw new Error('un is not set!')
}
var v3 = un
Run Code Online (Sandbox Code Playgroud)
或者是否有任何理论障碍,为什么这不是,也永远不可能?
Cer*_*nce 83
throw只是一个声明 ; 它可能不存在于需要表达式的位置.出于类似的原因,例如,你不能在if那里发表声明
var something = false || if (cond) { /* something */ }
Run Code Online (Sandbox Code Playgroud)
也是无效的语法.
只允许将表达式(计算为值的事物)分配给变量.如果你想throw,你必须要throw为一份声明中,这意味着你不能把它赋值的右手边.
我想一种方法是在右侧使用IIFE ||,允许您在该函数的第一行使用语句:
var un = undefined
var v2 = un || (() => { throw new Error('nope') })();Run Code Online (Sandbox Code Playgroud)
但那很奇怪.我更喜欢明确的if- throw.
Pat*_*eck 32
你的问题是一个赋值需要一个表达式,但你给它一个语句
初始化/赋值变量的语法是:
var|let|const <variableName> = <expression>
Run Code Online (Sandbox Code Playgroud)
但你用
var|let|const <variableName> = <statement>
Run Code Online (Sandbox Code Playgroud)
这是无效的语法.
表达式是产生值的东西.
值是Javascript中的任何类型
表达式的示例:
var x = 5;
Run Code Online (Sandbox Code Playgroud)
x 被赋值为"5"
var x = myFunc();
Run Code Online (Sandbox Code Playgroud)
myFunc() 生成一个分配给x的值
函数的生成值是它的返回值 - 函数总是返回,如果没有显式,则返回undefined.
函数具有额外的好处,能够在其正文中包含语句 - 这将是您的问题的解决方案 - 但稍后会更多.
声明是执行操作的内容.例如:
for (var i = 0; i < 10; i++) { /* loop body */ }
Run Code Online (Sandbox Code Playgroud)
该循环执行循环体10次的动作
throw new Error()
Run Code Online (Sandbox Code Playgroud)
展开堆栈并停止当前帧的执行
如果要分配给变量,则需要表达式,因为您希望变量具有值.
如果你考虑一下,应该很清楚,它永远不会用于声明.给变量一个"动作"是无稽之谈.那甚至应该是什么意思?
因此,您不能使用该throw语句,因为它不会产生值.
你只能拥有一个或另一个.无论是你的are (expression)东西还是你的do (statement)东西.
您可以通过将任何语句包装到函数中来将其转换为表达式,我建议使用IIFE (Immediately invoked function expression)- 基本上是一个调用自身的函数 - 来做到这一点
var x = 5 || (() => throw new Error())()
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为右侧现在是一个函数,而函数是一个产生值的表达式.
从技术上讲,没有任何东西阻止这种工作.
许多语言(c ++,...)实际上已经被undefined视为表达式.有些人(kotlin,......)甚至完全忽略了陈述,并将一切都视为表达.
其他(c#,php,...)提供了类似thrownull隐藏或??elvis运算符的解决方法来解决这个用例.
也许在未来我们会将这些功能中的一个纳入ecmascript标准(甚至有一个包含此功能的公开提议),直到那时你最好的选择是使用如下功能:
function assertPresent(value, message)
{
if(!value) {
throw new Error(message);
} else {
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
Nin*_*olz 20
您可以将异常的抛出移动到函数中,因为它throw是控制流的声明,而不是表达式:
一个表达式是代码的任何有效单元,其解析为一个值.
const throwError = function (e) { throw new Error(e); };
var un = undefined,
v3 = un || throwError('un is not set!');Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3935 次 |
| 最近记录: |