Estou preso a este conceito de 'Funções que retornam funções'. Estou me referindo ao livro 'Javascript Orientado a Objetos' de Stoyan Stefanov.
Snippet One:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b();
}
var s = a();
alert('break');
s();
Resultado:
A!
B!
break
Snippet Two
function a() {
alert('A!');
function b(){
alert('B!');
}
return b;
}
var s = a();
alert('break');
s();
A!
break
B!
Alguém pode me dizer a diferença entre retornar b
e b()
nos trechos acima?
javascript
Cafecorridor
fonte
fonte
Respostas:
Atribuir uma variável a uma função (sem o parêntese) copia a referência à função. Colocando o parêntese no final do nome de uma função, chama a função, retornando o valor de retorno da função.
Demo
Em seu exemplo, você também está definindo funções dentro de uma função. Tal como:
A função ainda pode ser chamada. Ainda existe. Isso é usado em JavaScript o tempo todo. As funções podem ser passadas ao redor apenas como outros valores. Considere o seguinte:
A função count pode manter as variáveis que foram definidas fora dela. Isso é chamado de encerramento. Também é muito usado em JavaScript.
fonte
this
significa apenas algo dentro de um corpo de função, caso contrário, é global. O que você está dizendothis.sayName
é que deseja a variável globalsayName
que não existe, é indefinida, portanto, não pode ser chamada.Retornar o nome da função sem
()
retorna uma referência à função, que pode ser atribuída como você fezvar s = a()
.s
agora contém uma referência à funçãob()
e chamars()
é funcionalmente equivalente a chamarb()
.Chamar a função com
()
em uma instrução de retorno executa a função e retorna qualquer valor retornado pela função. É semelhante a chamarvar x = b();
, mas em vez de atribuir o valor de retorno deb()
você o está retornando da função de chamadaa()
. Se ab()
própria função não retornar um valor, a chamada retornaráundefined
após qualquer outro trabalho realizado porb()
.fonte
return b();
chama a função b () e retorna seu resultado.return b;
retorna uma referência à função b, que você pode armazenar em uma variável para chamar mais tarde.fonte
Retornar
b
é retornar um objeto de função. Em Javascript, as funções são apenas objetos, como qualquer outro objeto. Se você achar que isso não ajuda, apenas substitua a palavra "objeto" por "coisa". Você pode retornar qualquer objeto de uma função. Você pode retornar um valor verdadeiro / falso. Um número inteiro (1,2,3,4 ...). Você pode retornar uma string. Você pode retornar um objeto complexo com várias propriedades. E você pode retornar uma função. uma função é apenas uma coisa.No seu caso, retornar
b
retorna a coisa, a coisa é uma função que pode ser chamada. Retornarb()
retorna o valor retornado pela função que pode ser chamada.Considere este código:
Usando a definição acima,
return b();
retorna o valor 42. Por outro lado,return b;
retorna uma função, que por sua vez retorna o valor 42. São duas coisas diferentes.fonte
42
;)Quando você retorna
b
, é apenas uma referência à função b, mas não está sendo executada neste momento.Ao retornar
b()
, você está executando a função e retornando seu valor.Tente
alert
ingtypeof(s)
em seus exemplos. O trecho b lhe dará 'função'. O que um snippet dará a você?fonte
s
. Tente emreturn this
vez dereturn b
embora ... Você será capaz de fazers.b()
então;)Imagine a função como um tipo, como um int. Você pode retornar ints em uma função. Você também pode retornar funções, elas são objetos do tipo "função".
Agora o problema de sintaxe: porque funções retornam valores, como você pode retornar uma função e não seu valor de retorno?
omitindo colchetes! Porque sem colchetes, a função não será executada! Assim:
Irá retornar a "função" (imagine como se você estivesse retornando um número), enquanto:
Primeiro executa a função e depois retorna o valor obtido ao executá-la, é uma grande diferença!
fonte
Crie uma variável :
Declare uma função :
Alerte o valor de
thing1
(nossa primeira variável):Agora, se quiséssemos
thing1
ser uma referência para a funçãosomething1
, o que significa que seria a mesma coisa que nossa função criada, faríamos:No entanto, se quisermos o
return
valor da função, devemos atribuir a ela o valor de retorno da função executada. Você executa a função usando parênteses:fonte
Snippet um:
a declaração 'b ()' significa executar a função chamada 'b' que mostra uma caixa de diálogo com o texto 'B!'
a instrução 'return b ();' significa executar uma função chamada 'b' e então retornar qual função 'b' retornou. mas 'b' não retorna nada, então esta instrução 'return b ()' também não retorna nada. Se b () retornar um número, então 'return b ()' também será um número.
Agora 's' é atribuído o valor do que 'a ()' retorna, que retorna 'b ()', que não é nada, então 's' não é nada (em JavaScript é uma coisa na verdade, é um 'indefinido'. quando você pede ao JavaScript para interpretar que tipo de dados é o 's', o interpretador JavaScript lhe dirá 's' é um indefinido.) Como 's' é um indefinido, quando você pede ao JavaScript para executar esta instrução 's ()', você está pedindo ao JavaScript para executar uma função chamada 's', mas 's' aqui é um 'indefinido', não uma função, então o JavaScript reclamará, "ei, s não é uma função, não sei como a fazer com este s ", então uma mensagem de erro" Uncaught TypeError: s não é uma função "será mostrada por JavaScript (testado no Firefox e Chrome)
Snippet Two
agora, a função 'a' retornando um ponteiro / alias para uma função chamada 'b'. então, quando executar 's = a ()', 's' obterá um valor apontando para b, ou seja, 's' é um apelido de 'b' agora, chamar 's' é igual a chamar 'b'. ie 's' é uma função agora. Execute 's ()' significa executar a função 'b' (o mesmo que executar 'b ()'), uma caixa de diálogo mostrando 'B!' aparecerá (ou seja, executando a instrução 'alert (' B! '); na função' b ')
fonte
Isso é muito útil na vida real.
Trabalhando com Express.js
Portanto, seu
express
trajeto normal é assim:Mas e se você precisar adicionar algum wrapper, manipulador de erros ou smth?
Em seguida, você invoca sua função de um invólucro.
Parece complicado? Bem, que tal isto:
Veja no final que você está passando uma função
loggingWrapper
com um argumento como outra funçãoitWorksHandler
, e vocêloggingWrapper
retorna uma nova função que recebereq, res, next
como argumentos.fonte