My trick for a similar question
正如大多数其他答案中提到的那样,throw 是一个语句而不是一个表达式。这仅仅意味着它不能用于期望分配值的地方。我们可以创建一个会抛出错误的函数,但在这里我有一个不会创建额外的堆栈调用的机制,希望它更容易调试。 null.throwFooNotSet() 保证总是抛出错误,因为不会有任何属性添加到 null 原始值。我已经添加了所有的 try、catch 和 finally 语句来解决这个问题。特殊类型的一元前缀运算符(请注意它是一个前缀运算符,如 +x --x ++x !x 和 void 它不是一个函数,所以不要用括号调用它(尽管实际上它会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
}
}()