2014-01-06 3 views
1

Почему в JavaScript JavaScript недопустимо?Javascript - почему это выражение недействительно?

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

Это потому, что существуют ограничения на позиционирование ключевого слова throw?

+0

@cocco - no Я считаю, что допустимый синтаксис – Ben

+1

'throw ...' не оценивает выражение? –

+0

@ Аnders - есть ли идиоматический способ добиться того, чего я хочу? – Ben

ответ

1

Проблема связана с типом и видом операций, которые вы делаете:

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

Тройной оператор expectes выражения, и бросить «», как это утверждение. Если вы хотите использовать это трехкомпонентное выражение в любом случае сделать это вместо того, чтобы:

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() {}) - объект функции типа, который вы можете использовать в тройном выражении.

С уважением.

+0

В скрипке я добавил 1! = 1, чтобы имитировать вашу переменную foo. –

4

throw - заявление, а не выражение. Вы можете использовать только выражения в тройном if оператора.

+0

"throw expression;" это утверждение, «throw», так же как это ключевое слово языка. –

0

My trick for a similar question

Как упомянуто в большинстве других ответов throw это утверждение не является выражением. Это просто означает, что он не может использоваться в тех местах, где ожидается присвоение значения. Мы могли бы создать функцию, которая будет вызывать ошибку, но здесь у меня есть механизм, который не будет создавать дополнительный вызов стека, что облегчает его отладку. null.throwFooNotSet() гарантированно всегда выдает ошибку, так как никогда не будет добавлено никаких свойств в примитивное значение null. Я добавил все заявления try, catch и finally, чтобы прояснить это. Специальный тип unary prefix operator (обратите внимание, что это префиксный оператор, такой как +x--x++x!x и void это не функция, поэтому не вызывайте его с помощью parens (даже если это действительно будет работать) безопасно звонить, даже когда значение не определен. Так что, возможно, все пропустили пункт этого вопроса. Если вы не требуете о том, почему вы не можете бросить с тройным нижеследующее может быть все, что вам нужно.

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

TypeOf не работает значения, определенные с let. но не имеет смысла определять глобальные переменные, пусть в любом случае, в строгом режиме новые переменные не могут быть определены с помощью eval, поэтому вы можете найти все объявленные переменные, проанализировав статический код. свойства непосредственно в глобальном объекте, поэтому в браузере window.MY_UGLY_GLOBAL='foo' и это можно проверить для существования с помощью ключевого слова 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 
    } 
}() 
Смежные вопросы