Eu escrevi o seguinte script apenas para ver o que acontece quando uma variável e uma função que tem uma função atribuída a ela têm seus nomes conflitantes:
var f = function() {
console.log("Me original.");
}
function f() {
console.log("Me duplicate.");
}
f();
A saída que estou recebendo é "Me original". Por que a outra função não foi chamada?
Além disso, se eu alterar minha atribuição original para var f = new function() {
, recebo "Me original", seguido por uma mensagem TypeError object is not a function
. Alguém pode explicar?
javascript
function
ankush981
fonte
fonte
Respostas:
As declarações de função são içadas (movidas para o topo) em JavaScript. Embora incorreto em termos de ordem de análise, o código que você possui é semanticamente igual ao seguinte, já que as declarações de função são suspensas:
Que por sua vez, com exceção do nome da função é o mesmo que:
Que por sua vez, por causa do içamento variável é o mesmo que:
O que explica o que você está recebendo, você está substituindo a função. De forma mais geral, várias
var
declarações são permitidas em JavaScript -var x = 3; var x = 5
é perfeitamente legal. No novo padrão ECMAScript 6, aslet
declarações proíbem isso.Este artigo de @kangax faz um trabalho fantástico em desmistificar funções em javascript
fonte
function f()
avar f = function()
tanto? Os nomes de içamento e função são realmente a única diferença?f
são içadas, e a"Me Original"
versão é içada mais tarde , cada uma é movida para o topo, mas na mesma ordem. Gostaria apenas de acrescentar que, em geral, você não deve nomear várias funções da mesma maneira :)var
o mesmo nome duas vezes no mesmo escopo.Se não parecer que alguém respondeu à sua pergunta de acompanhamento, vou respondê-la aqui, embora você deva fazer perguntas de acompanhamento como perguntas separadas.
Você perguntou por que isso:
imprime "Me original". e então um erro.
O que está acontecendo aqui é que
new
faz com que a função seja usada como um construtor. Portanto, isso é equivalente ao seguinte:E graças à função de içamento que Benjamin explicou, o acima é essencialmente equivalente a este:
Esta expressão:
faz com que um novo objeto seja construído e atribuído a ele
f
, usando uma função anônima como o construtor. "Eu original." é impresso conforme o construtor é executado. Mas o objeto que é construído não é em si uma função, então, quando isso eventualmente for executado:você obtém um erro, porque
f
não é uma função.fonte
Perdoe-me se esta é a maneira errada de abordar a adição de um ponto. Não tenho estado muito por aqui e gostaria de receber orientações e / ou críticas construtivas.
A resposta de Benjamin aborda a pergunta do OP de maneira excelente, mas eu gostaria de adicionar um ajuste que nos dará um tour completo de içamento e suas esquisitices.
Se começarmos o código original com uma chamada para
f
, assim:A saída será:
A razão é que
var
efunction
declarações são levantadas de maneiras ligeiramente diferentes.Para
var
a declaração é movido para o topo do escopo atual *, mas qualquer atribuição não é içada. No que diz respeito ao valor do var declarado, ele é indefinido até que a linha de atribuição original seja alcançada.Para
function
declarações , tanto a declaração quanto a definição são suspensas. Expressões de função , conforme usadas novar f = function() {...
construção, não são içadas.Portanto, após o içamento, a execução é como se o código fosse:
* Todo escopo do JavaScript é léxico, ou função, escopo, mas parecia que apenas confundiria as coisas usar a palavra f naquele ponto.
fonte