Usamos instruções de retorno opcionalmente em funções JavaScript. É uma palavra-chave. Mas qual é o tipo real de return
si mesmo. Na verdade fiquei confuso, vendo o exemplo:
function add(a, b) {
return (
console.log(a + b),
console.log(arguments)
);
}
add(2, 2);
Resultado:
4
[2, 2]
Portanto, podemos passar expressões separadas por vírgulas para a return
instrução. Isso é uma função?
E começando com isso, podemos adivinhar que todas as palavras-chave em JavaScript são, em última análise, uma função?
Escrevi um pequeno blog como uma essência dessa discussão. Você pode querer verificar isso aqui .
javascript
return
keyword
Arnab Das
fonte
fonte
var a = (2 + 2)
.var a = (1, 2)
- isso resultará ema
ter o valor2
devido a como o operador vírgula opera (sim, vírgula é um operador matemático como+
ou|
etc, especificamente, no cálculo lambada, o operador vírgula implementa o combinador K)Respostas:
Não tem um tipo, não é um valor.
A tentativa
typeof return;
vai te darUnexpected token return
.Não, embora parênteses possam ser usados para chamar uma função, aqui eles são um operador de agrupamento contendo algumas expressões separadas por um operador vírgula .
Uma demonstração mais útil seria:
Que sai
0
porque o resultado dea + b
é ignorado (está no LHS do operador vírgula) ea - b
é retornado.fonte
return
não consegue vê-los, que é o que você estava perguntando.a + b
apenas não tem efeito visível porque não tem efeitos colaterais e o valor é descartado (bem, dado que não tem efeito prático, é possível que um compilador otimizador possa removê-lo, mas isso não faz diferença prática).if
) é a avaliação de curto-circuito. O operador vírgula não causa curto-circuito, por isso avalia os dois lados. Em seguida, ele retornará o último. Esse é explicitamente o objetivo do operador vírgula, para agrupar expressões em uma única instrução (geralmente o valor resultante de toda a instrução é ignorado), mais frequentemente usado para inicialização de variável:var i = 2, j = 3, k = 4;
Estou um pouco chocado que ninguém aqui tenha feito referência direta à especificação :
Então, por causa da especificação, seu exemplo lê:
return ( GetValue(exprRef) )
Onde
exprRef = console.log(a + b), console.log(arguments)
Que de acordo com as especificações do operador vírgula ...
... significa que cada expressão será avaliada até o último item da lista de vírgulas, que se torna a expressão de atribuição. Então, seu código
return (console.log(a + b) , console.log(arguments))
vai1.) imprimir o resultado de
a + b
2.) Nada é deixado para executar, então execute a próxima expressão que
3.) imprime o
arguments
, e porqueconsole.log()
não especifica uma instrução de retorno4.) Avalia como indefinido
5.) Que é então devolvido ao chamador.
Portanto, a resposta correta é,
return
não tem um tipo, só retorna o resultado de alguma expressão.Para a próxima pergunta:
Não. A vírgula em JavaScript é um operador, definido para permitir que você combine várias expressões em uma única linha, e é definida pela especificação para retornar a expressão avaliada do que quer que seja por último em sua lista.
Você ainda não acredita em mim?
Brinque com esse código aqui e mexa com o último valor da lista. Ele sempre retornará o último valor da lista, no seu caso, é
undefined.
Para sua pergunta final,
Novamente, não. As funções têm uma definição muito específica na linguagem. Não vou reimprimi-lo aqui porque essa resposta já está ficando extremamente longa.
fonte
Testando o que acontece quando você retorna valores entre parênteses:
Dá a resposta
2
, então parece que uma lista de valores separados por vírgulas é avaliada como o último elemento da lista.Na verdade, os parênteses são irrelevantes aqui, eles estão agrupando operações em vez de significar uma chamada de função. O que é possivelmente surpreendente, porém, é que a vírgula é válida aqui. Eu encontrei uma postagem de blog interessante sobre como a vírgula é tratada aqui:
https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/
fonte
return ([1, 2])
deve imprimir os dois valores?console.log((1, 2))
return
não é uma função. É a continuação da função em que ocorre.Pense na instrução em
alert (2 * foo(bar));
quefoo
é o nome de uma função. Ao avaliar, você vê que precisa deixar de lado o resto da afirmação por um momento para se concentrar na avaliaçãofoo(bar)
. Você pode visualizar a parte que você deixa de lado como algo semelhantealert (2 * _)
, com um espaço em branco para preencher. Quando você sabe qual é o valor defoo(bar)
, você o pega novamente.O que você deixou de lado foi a continuação da ligação
foo(bar)
.Chamando
return
alimenta um valor a que a continuação.Quando você avalia uma função interna
foo
, o restante defoo
espera que essa função seja reduzida a um valor e, em seguida, éfoo
reiniciado. Você ainda tem uma meta para avaliarfoo(bar)
, apenas pausada.Quando você avalia
return
internamentefoo
, nenhuma parte defoo
espera por um valor.return
não se reduz a um valor no localfoo
onde você o usou. Em vez disso, faz com que toda a chamadafoo(bar)
seja reduzida a um valor, e o objetivo "avaliarfoo(bar)
" é considerada completa e perdida.As pessoas geralmente não falam sobre continuações quando você é novo em programação. Eles pensam nisso como um tópico avançado, apenas porque não são coisas muito avançadas que as pessoas eventualmente, fazer com continuações. Mas a verdade é que você os usa o tempo todo, toda vez que chama uma função.
fonte
alert(2 * _)
para uso posterior em Javascript (há uma notação diferente para fazer esse tipo de coisa).return
de dentrofoo
não é um valor; você não poderia empacotá-lo em uma estrutura de dados, atribuí-lo a uma variável, esperar um pouco e então alimentar algo mais tarde - e você não poderia alimentá-lo mais de uma vez. Mas, como eu disse, tópicos avançados.my_if
função que se comporte como integradaif()then{}else{}
, e não conseguir fazê-lo mesmo que se permita usar a função integrada - não terrivelmente avançada e extremamente instrutiva, especialmente se você vai terminar no código que passa por callbacks.o
return
aqui é um arenque vermelho. Talvez seja interessante a seguinte variação:que sai como a última linha
porque a função não retorna nada. (Ele retornaria o valor de retorno do segundo
console.log
, se houvesse um).Como está, o código é exatamente idêntico ao
fonte
Uma maneira interessante de entender a instrução return é por meio do operador void Dê uma olhada neste código
Uma vez que a
return
instrução recebe um argumento que é[[expression]]
e retorna para o chamador na pilha, ou seja,arguments.callee.caller
ela será executadavoid(expression)
e retornaráundefined
a avaliação do operador void.fonte