为什么以下表达式在JavaScript中无效?
(function(){ return foo ? foo : throw "foo not set"; }())
是因为throw关键字的定位有限制吗?
答案 0 :(得分:6)
这个问题已在这里得到解答:
JavaScript error handling: can I throw an error inside a ternary operator?
throw
是一个声明,它不能成为表达式的一部分。
答案 1 :(得分:4)
throw
是一个陈述,而不是表达。您只能在三元if
运算符中使用表达式。
答案 2 :(得分:1)
问题与您正在进行的操作的类型和类型有关:
(function(){ return foo ? foo : throw "foo not set"; }())
三元运算符预先指出一个表达式,并像这样抛出“”是一个语句。 如果你想使用那个三元表达式,请改为:
function doSomething(){
return foo ? (function(){ return foo; }) : (function(){ throw "error"; });
}
try
{
var result = doSomething()();
alert(result);
}
catch(e){
alert(e);
}
这是一个小提琴,所以你可以更好地理解:http://jsfiddle.net/9K3hv/
这样你决定了操作的类型,然后你调用它,因为(function(){}) 是函数类型的对象,您可以在三元表达式中使用它。
问候。
答案 3 :(得分:0)
My trick for a similar question
正如大多数其他答案所提到的throw
是一个陈述而不是表达。这仅仅意味着它不能用于预期赋值的地方。我们可以创建一个会抛出错误的函数,但是在这里我有一个不会创建额外堆栈调用的机制,这使得它有望更容易调试。保证null.throwFooNotSet()
始终抛出错误,因为永远不会有任何属性添加到null
原始值。我已经添加了所有try,catch和finally语句来清除它。特殊类型的一元前缀运算符(请注意它是一个前缀运算符,如+x
--x
++x
!x
和void
它不是函数所以不要即使没有定义一个值,也可以用parens来调用它(即使它实际上会起作用)也是安全的。所以也许每个人都错过了这个问题的重点。如果你不问为什么你不能从三元组中抛出以下可能是您所需要的。
0|| function(){
return typeof foo !== 'undefined'
? foo
: 'enter default value here'
}()
typeof不适用于使用let定义的值。但是无论如何定义全局变量没有多大意义,在严格模式下,新变量不能用eval定义,所以你可以通过分析静态代码找到所有声明的变量。您仍然可以直接向全局Object添加属性,因此在浏览器window.MY_UGLY_GLOBAL='foo'
中可以使用in
关键字检查是否存在,但是如果声明变量,则使用in将无效全局Object和检查它存在的函数之间的闭包......但正如我之前所说,您可以读取代码并查看它是否存在。所以真正唯一有意义的是检查全局Object,并且通过使用in,JS引擎不会抓取作用域链,因此它会更加快速查找。如果你正在缩小你的脚本,你现在必须确定你没有破坏这个属性的名称,因为它现在必须用它的名字来引用。
window.MY_UGLY_VAR = undefined
if ('MY_UGLY_VAR' in window)
console.log(
'despite being assigned the value undefined, "MY_UGLY_GLOBAL"'
+'is "in" the window object')
从三元组中抛出:只需在null上调用一个不存在的属性。
0 || function(){
'use strict'
var valToReturn
, defaultVal = 'foobar'
//, foo = 'foo'
try {
0|| function () {
valToReturn = typeof foo !== 'undefined' ? foo : null.throwFooNotSet() }()
// let foo = 'bar'
} catch(e){
valToReturn = defaultVal
if(e.message && e.message.indexOf('throwFooNotSet') !== -1)
console.log('no value for foo')
else
console.log('es2015 let temporal dead zone')
} finally {
return valToReturn
}
}()