【问题标题】:Javascript - why is this expression invalid?Javascript - 为什么这个表达式无效?
【发布时间】:2014-01-06 11:51:01
【问题描述】:

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

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

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

【问题讨论】:

  • @cocco - 不,我认为这是有效的语法
  • throw... 不计算为表达式?
  • @Anders - 有没有一种惯用的方法来实现我想要的?
  • @cocco,自己试试吧。它是有效的语法(以及许多其他方法,因为我们只需要将 FunctionDeclaration 转换为 FunctionExpression)
  • @cocco - 在浏览器中运行 - 它是有效的语法:(function(){ return "foo"; }())

标签: javascript


【解决方案1】:

这里已经回答了这个问题:

JavaScript error handling: can I throw an error inside a ternary operator?

throw 是一个语句,它不能是表达式的一部分。

【讨论】:

  • 可以!如果它是由 (function(){}) 组成的表达式的一部分。
【解决方案2】:

throw 是一个语句,而不是表达式。您只能在三元 if 运算符中使用表达式。

【讨论】:

  • "抛出表达式;"是一个语句,“throw”就像是语言的关键字一样。
【解决方案3】:

问题与您正在执行的操作的类型和种类有关:

(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(){}) 是函数类型的对象,您可以在三元表达式中使用它。

问候。

【讨论】:

  • 在小提琴中我添加了 1!=1 来模拟你的 foo 变量。
【解决方案4】:

My trick for a similar question

正如大多数其他答案中提到的那样,throw 是一个语句而不是一个表达式。这仅仅意味着它不能用于期望分配值的地方。我们可以创建一个会抛出错误的函数,但在这里我有一个不会创建额外的堆栈调用的机制,希望它更容易调试。 null.throwFooNotSet() 保证总是抛出错误,因为不会有任何属性添加到 null 原始值。我已经添加了所有的 try、catch 和 finally 语句来解决这个问题。特殊类型的一元前缀运算符(请注意它是一个前缀运算符,如 +x --x ++x !xvoid 它不是一个函数,所以不要用括号调用它(尽管实际上它会work) 即使在未定义值的情况下也可以安全调用。所以也许每个人都错过了这个问题的重点。如果您不是在问为什么不能从三元中抛出,那么以下可能就是您所需要的。

0|| function(){
  return typeof foo !== 'undefined'
  ? foo 
  : 'enter default value here'
}()

typeof 不适用于用 let 定义的值。但是无论如何用let定义全局变量并没有多大意义,在严格模式下无法用eval定义新变量,因此您可以通过分析静态代码找到所有已声明的变量。您仍然可以直接将属性添加到全局对象,因此在浏览器中 window.MY_UGLY_GLOBAL='foo' 并且可以使用 in 关键字检查其是否存在,但如果变量在全局对象和检查它是否存在的函数......但正如我之前所说,您可以阅读代码并查看它是否存在。所以真正需要检查的唯一地方是全局对象,通过使用 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 
   }
 }()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多