Prefácio
No ECMAScript, existem dois métodos mais usados para criar objetos de função, ou seja, usando expressões de função ou usando declarações de função. Nesse sentido, a especificação do ECMAScript deixa claro que as declarações de função devem sempre transportar um identificador, que é o que chamamos de nome da função, e as expressões de função podem ser omitidas. Vamos dar uma olhada na introdução detalhada das diferenças entre os dois.
O que é a declaração de função?
A declaração da função pode definir variáveis de função nomeadas sem atribuir valores às variáveis. A declaração de função é uma estrutura independente que não pode ser aninhada em módulos não funcionais. Pode ser comparado à declaração variável. Assim como a declaração variável deve começar com "var", a declaração da função deve começar com "função".
Por exemplo
barra de função () {return 3;}ECMA 5 (13.0) Sintaxe Definição:
function Identifier ( FormalParameterList[opt] ) { FunctionBody }
Os nomes de funções estão disponíveis em seu próprio escopo e escopo dos pais (caso contrário, a função não estará disponível).
barra de função () {return 3;} bar () // 3bar // funçãoO que é a expressão da função?
A expressão da função define uma função como parte de uma declaração de expressão (geralmente atribuição variável). As funções definidas pela expressão da função podem ser nomeadas ou anônimas. A expressão da função não pode começar com a "função" (os seguintes exemplos de auto-calma devem ser fechados entre colchetes).
Por exemplo
// Função anônima ExpressionVar A = function () {return 3;} // Nomeado Função ExpressionVar A = Função Bar () {return 3;} // Expressão da função auto -invocada (função SayHello () {alert ("hello!");}) ();ECMA 5 (13.0) Sintaxe Definição:
function Identifieropt ( FormalParameterList[opt] ) { FunctionBody }
(Esta definição parece incompleta porque ignora uma condição: a afirmação periférica é uma expressão e não começa com "função")
Nomes de funções (se houver) não estão disponíveis fora do escopo (em comparação com a declaração de função).
Então, o que é a declaração de função?
A declaração de função às vezes é outra declaração de função. Mas Kangax ressalta que, em Mozilla, a declaração de função é uma extensão da declaração de função, permitindo que a declaração de declaração de função seja usada em qualquer lugar que permita o uso de instruções. No entanto, a declaração de função não é o padrão agora, portanto, não é recomendável ser usado no desenvolvimento do produto.
Vamos começar com alguns pequenos testes. Adivinha o que aparecerá nas situações a seguir?
Pergunta 1:
function foo () {barra function () {return 3; } barra de retorno (); barra de função () {return 8; }} alert (Foo ());Pergunta 2:
function foo () {var bar = function () {return 3; }; barra de retorno (); var bar = function () {return 8; };} alert (foo ());Pergunta 3:
alert (Foo ()); função foo () {var bar = function () {return 3; }; barra de retorno (); var bar = function () {return 8; };}Pergunta 4:
function foo () {return bar (); var bar = function () {return 3; }; var bar = function () {return 8; };} alert (foo ());Se sua resposta não for 8, 3, 3 e [Erro de tipo: a barra não é uma função], continue lendo ... (mesmo se você responder corretamente, você deve continuar lendo)
Agora vamos explicar o teste anterior.
A pergunta 1 usa a declaração da função, o que significa que eles são içados ...
Espere, o que está iça?
Aqui está uma citação de Ben Cherry: "A declaração de função e a variável de função geralmente são movidas ('higiênicas') para o topo do escopo atual do intérprete JavaScript".
Quando a declaração da função for promovida, todo o corpo da função será promovido de acordo, portanto, o código da pergunta 1 é executado como este após ser explicado pelo intérprete:
// ** Sequência de processamento simulado para a pergunta 1 ** function foo () {// Defina barra de barra quando a barra de função () {return 3; } // Redefina a barra de função de TI () {return 8; } // retorna sua barra de retorno de invocação (); // 8} alerta (Foo ());No entanto, somos frequentemente informados de que o código por trás da declaração de devolução não pode ser executado ...
Durante a execução do JavaScript, existem dois conceitos: o contexto (ECMA 5 quebra -o em lexicalenvironment, variável ambiente e essa ligação) e processo (uma série de declarações chamadas em sequência). Quando o programa entra no domínio da execução, a declaração causa o ambiente variável. Eles são diferentes da declaração (como devolução) e não seguem as regras de execução da declaração.
A expressão da função será promovida?
Depende da expressão. Por exemplo, a primeira expressão na pergunta 2:
var bar = function () {return 3;};A (barra var) à esquerda do sinal igual é a declaração variável. A declaração variável será promovida, mas a expressão de atribuição não. Portanto, quando a barra for promovida, o intérprete será inicializado assim: var bar = indefinido. A própria definição da função não será promovida.
(ECMA 5 12.2 Variáveis com Initialzier são atribuídas pela atribuição de expressão quando a variável é executada, não quando a variável é criada.)
Portanto, o código da pergunta 2 será executado na seguinte ordem:
// ** Sequência de processamento simulado para a pergunta 2 ** function foo () {// Uma declaração para cada expressão de função var bar = indefinida; var bar = indefinido; // A expressão da primeira função é executada bar = function () {return 3; }; // a função criada pela primeira função expressão é invocada barra de retorno (); // Expressão da segunda função inacessível} alert (Foo ()); // 3Você pode dizer que isso pode ser explicado, mas a resposta à pergunta 3 está errada. Vou relatar um erro ao executar o Firebug.
Salve o código em um arquivo HTML e tente executá -lo no Firefox. Ou execute no console IE8, Chrome ou Safari. Obviamente, o console do Firebug não promoverá a função ao executar o código no escopo "global" (na verdade não é global, mas o escopo "Firebug" exclusivo - basta tentar executar "esta == janela" no console do Firebug).
A pergunta 3 e a pergunta 1 têm lógica semelhante. Desta vez, a função Foo foi promovida.
A pergunta 4 é muito simples, não há melhoria de função ...
Pode -se dizer que, mas se não houver melhorias, o TypeError será "bar não definido" em vez de "bar não uma função". De fato, não há melhoria de função neste exemplo, mas há melhorias variáveis. Portanto, a barra é declarada no início, mas seu valor não é definido. Os outros códigos são executados em ordem.
// ** Sequência de processamento simulado para a pergunta 4 ** function foo () {// Uma declaração para cada expressão de função var bar = indefinido; var bar = indefinido; barra de retorno (); // typeError: "bar não definido" // nenhuma expressão de função é atingida} alert (foo ());Para que mais você deve prestar atenção?
O oficial proíbe o uso da declaração de função em módulos não funcionais (como se). No entanto, todos os navegadores o sustentam, mas suas explicações são diferentes.
Por exemplo, o snippet de código a seguir lançará um erro no Firefox 3.6 porque interpreta a declaração da função como declaração de função (veja acima), então X não é definido. Mas no IE8, Chrome 5 e Safari 5, a função x será retornada (o mesmo que a declaração de função padrão).
function foo () {if (false) {function x () {}; } retornar x;} alert (foo ());Pode -se observar que o uso da declaração de função pode causar confusão, então ela tem alguma vantagem?
Você pode dizer que a declaração da função está bastante solta - se você tentar usar uma função antes da declaração, a promoção pode realmente corrigir a ordem para que a função possa ser chamada corretamente. Mas esse tipo de folga não é propício à codificação rigorosa e, de uma perspectiva de longo prazo, é provável que promova, em vez de evitar acidentes. Afinal, há uma razão pela qual os programadores organizam declarações em uma ordem específica.
Então, existem outros motivos para apoiar a expressão da função?
O que você acha?
1) A declaração da função parece imitar as declarações do método do estilo Java, mas os métodos Java não são os mesmos que o JavaScript. No JavaScript, as funções são objetos vivos com valores. Os métodos Java são apenas o armazenamento de metadados. As duas peças a seguir definem a função, mas apenas a expressão da função parece um objeto é criado.
// função declaraçãofunctionfunção add (a, b) {return a + b}; // function ExpressionVar add = function (a, b) {return a + b};2) A expressão da função tem mais usos. A declaração de função só pode existir em órfãos como uma "declaração". Tudo o que pode fazer é criar uma variável de objeto no escopo atual. A expressão da função, por definição, faz parte de uma grande estrutura. Se você deseja criar funções anônimas, adicione funções aos protótipos ou use funções como propriedade de outros objetos, você pode usar a expressão da função. Sempre que você usa aplicativos avançados, como curry ou compor, você usa a expressão da função ao criar novas funções. A expressão da função e a programação funcional são inseparáveis.
// função expressão de expressão dizhello = alert.curry ("hello!");Existem desvantagens na expressão da função?
A expressão da função cria a maioria das funções anônimas. Por exemplo, a seguinte função é anônima, hoje é apenas uma referência a uma função anônima:
var Today = function () {return new Date ()}Isso será problemático? Não na maioria dos casos, mas como Nick Fitzgerald apontou, as funções anônimas de depuração podem ser irritantes. Ele recomenda o uso de expressões de função nomeada (NFES) como espaço de trabalho:
var Today = function Today () {return new Date ()}No entanto, como Asen Bozhilov disse (e a documentação de Kangax) não podem ser executados corretamente abaixo do IE9.
para concluir
Uma declaração de função colocada aleatoriamente é enganosa e raramente (se houver) situações, e atribuir valores a variáveis com expressão de função não pode substituir a declaração da função. Mas se a declaração da função for necessária, colocá -la na parte superior do escopo pode reduzir a confusão. Nunca coloque a declaração de função em uma instrução IF.
Dito tanto, a declaração da função pode ser útil em sua própria situação. Não é nada. O dogma do papel é perigoso e muitas vezes faz com que o código seja espancado ao redor do mato. Mais importante, você entende o conceito para poder decidir qual método criar a função com base em sua própria situação. O acima é o conteúdo inteiro deste artigo. Espero que este artigo seja útil para todos a esse respeito.