Declaração de função como var em vez de função

28

Mais e mais eu estou vendo funções sendo declaradas como

var foo = function() {

    // things
};

Em vez de como eu aprendi, como

function foo() {

    // things
}

Qual é a diferença? Melhor performance? Escopo? Devo estar usando esse método?

Steve Robbins
fonte
é importante notar que, em javascript, as funções são cidadãos de primeira classe . Isso permite que você repasse o comportamento como objetos. Isso é muito útil para retornos de chamada e delegação, entre outras coisas.
Chris Bye
Âmbito . O agrupamento de nomes de variáveis ​​"// things" está essencialmente /, esperançosamente, impedindo colisões de nomes dos "// things" que estão agrupando, com outros JavaScript (arquivos) incluídos. Outra maneira de pensar é que você criou um espaço para nome "foo".
Radarbob

Respostas:

25

var foo = function() {} define uma variável que referencia uma função anônima.

function foo() {}define uma função nomeada foo.

Qualquer um pode ser passado pelo nome como parâmetros de função e pode ser instanciado se o uso pretendido for para OOP.

No final do dia, qual você usa é amplamente determinado pelo seu caso de uso específico (o Javascript é divertido assim;)). Se você acabar usando o primeiro, sugiro fortemente que você nomeie a função:

var foo = function MY_function() {}. Essa convenção de nomenclatura ajuda o callstack do depurador a não ser inútil.

Demian Brecht
fonte
11
Tem uma brincadeira lá em function () MEU ...
Erik Reppen
11
@Demian Brecht, e a abordagem var foo = function foo () {...}?
shabunc
@shabunc: E quanto a isso? Está listado no último parágrafo da minha resposta.
Demian Brecht
@Demian Brecht, não, na verdade, na última variável parágrafo é chamado fooe função é chamadaMY_function
shabunc
@shabunc: O nome não importa. O que importa é o valor na pilha de chamadas. Como exemplo, [NAMESPACE] _ [nome fn] é a convenção usada pelo Mozilla. O nome em si não importa, desde que sua convenção seja consistente em todo o projeto.
Demian Brecht
13

expressão de função:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

A expressão func neste caso é anônima, mas atribuída a um var para referência. Isso é diferente de uma instrução de função rotulada das seguintes maneiras:

  • não pode ser içado (chamado antes de ser definido)
  • new someFunction().constructor.name === 'someFunction';//false As instâncias não obtêm o nome do var para constructor.name porque uma referência à função é atribuída ao var, mas o var, não a função, está vinculado ao nome do var

Em uma instrução de função rotulada:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • trabalhos de elevação
  • new someFunction().constructor.name === 'someFunction'; //true o nome está vinculado diretamente à função.

De um modo geral, não há realmente nenhuma grande razão para fazer expressão para var, a menos que você queira que as chamadas falhem se as coisas mudam ou você está definindo / atribuindo um método em uma linha. Na verdade, considero a elevação útil para organizar objetos com definições internas de função e método na parte inferior, para que eu possa entender o comportamento real do objeto e fazer definições de método público de uma linha (apenas atribuindo funcs ao this.mesmo nome), tudo em um local para facilitar a referência. Você deve sempre tentar usar instruções rotuladas para construtores, IMO, para poder identificar o 'tipo' de um objeto por meio de seu construtor.

Erik Reppen
fonte
8

Seu primeiro exemplo é uma expressão, enquanto o segundo exemplo é uma declaração . A definição de funções como expressões permite mais flexibilidade no local em que a definição pode ocorrer, no que você pode atribuí-la, que pode ser transmitida como parâmetro, etc.

Por exemplo:

SomeThing('abc', function(a,b) {return a*b;});

vs ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

Exemplos mais complexos se tornariam obcenamente complicados sem a sintaxe da expressão da função.

Veja /programming/111102/how-do-javascript-closures-work

gahooa
fonte
4

A principal diferença prática é a elevação. Por exemplo:

foo(); // alerts 'hello'
function foo() {alert('hello');}

vs

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Além disso, esse é um comportamento indefinido

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

enquanto isso estiver ok.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}
Austin
fonte
7
Não há absolutamente nada de errado em definir uma função dentro de uma função em JS. Não há muitos lugares em que você não pode definir uma função no JS.
precisa saber é o seguinte
2
@ErikReppen Você definitivamente não pode usar declarações de função em blocos não funcionais (como em uma instrução if). Parece que não consigo encontrar onde leio que eles não podem ser usados ​​em outra função.
Austin
@ Austin Também não há nada de errado com uma definição de função em uma ifinstrução!
Tim
@ Austin: Talvez você tenha lido na w3schools? ;)
Demian Brecht
2
As expressões de função @ErikReppen podem ser usadas em qualquer lugar. Declarações de função não podem ser. Veja stackoverflow.com/questions/10069204/…
Austin