Javascript - 为什么这个表达式无效?

时间:2014-01-06 11:51:02

标签: javascript

为什么以下表达式在JavaScript中无效?

(function(){ return foo ? foo : throw "foo not set"; }())

是因为throw关键字的定位有限制吗?

4 个答案:

答案 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 !xvoid它不是函数所以不要即使没有定义一个值,也可以用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 
   }
 }()