Pergunta

Há dois popular fechamento de estilos em javascript.O primeiro eu chamo anônimo construtor:

new function() { 
  var code...
}

e o inline funções executadas:

(function() {
  var code...
})();

existem diferenças de comportamento entre os dois?É um "melhor" sobre o outro?

Foi útil?

Solução

Ambos os casos irá executar a função, a única diferença real é que o valor de retorno da expressão pode ser, e que o valor de "este" vai ser dentro da função.

Basicamente, o comportamento de

new expression

É, efetivamente, o equivalente a

var tempObject = {};
var result = expression.call(tempObject);
if (result is not an object)
    result = tempObject;

Embora, claro, tempObject e o resultado são transitórios valores que você pode nunca ver (são detalhes de implementação do interpretador), e não há JS mecanismo para fazer o "não é um objeto de verificação".

De modo geral, o "novo function() { ..}" será o método mais lento devido à necessidade de se criar esse objeto para o construtor.

Que disse isso deve ser não ser uma diferença real como objeto de alocação não é lento, e você não deveria estar usando esse código no hot código (devido ao custo de criar a função de objeto e associados encerramento).

Editar:uma coisa que eu percebi que eu perdi com isso é que o tempObject vai ficar expressions protótipo, por exemplo.(antes de o expression.call) tempObject.__proto__ = expression.prototype

Outras dicas

@Lance:o primeiro é também a execução.Compare-o com o nome do construtor:

function Blah() {
    alert('blah');
}
new Bla();

este é, na verdade, também a execução do código.O mesmo vale para o anônimo construtor...

Mas essa não era a questão ;-)

Eles criam um fechamento ao executar o bloco de código.Como uma questão de estilo, eu prefiro muito mais o segundo por um par de razões:

Não é imediatamente óbvio, olhando para o primeiro que o código vai ser realmente executado;a linha de parece é a criação de uma nova função, em vez de executá-lo como um construtor, mas não é isso o que está acontecendo de verdade.Evite o código que não fazer o que parece que está fazendo!

Também o (function(){ ... })(); faça bom aparador de tokens de modo que você pode ver imediatamente o que está entrando e saindo de um fechamento de escopo.Isso é bom porque ele alerta o programador a lê-lo para a mudança de escopo, e é especialmente útil se você estiver fazendo alguma pós-processamento do arquivo, por exemplo, para a minimização.

Bem, eu fiz uma página como esta:

<html>
<body>
<script type="text/javascript">
var a = new function() { 
  alert("method 1");

  return "test";
};

var b = (function() {
  alert("method 2");

  return "test";
})();

alert(a);  //a is a function
alert(b);  //b is a string containing "test"

</script>
</body>
</html>

Surpreendentemente (para mim de qualquer maneira) é alertado tanto o "método 1" e 2 do método".Eu não esperava "método 1" para ser alertado.A diferença foi que os valores de a e b foram.uma foi a própria função, enquanto que b foi a seqüência de caracteres que a função devolvida.

O segundo exemplo irá executar a função após a sua criação.

editar:isto não é realmente verdade.

Sim, há diferenças entre os dois.

Ambos são funções anônimas e executar exatamente da mesma forma.Mas, a diferença entre os dois é que no segundo caso, o escopo das variáveis é restrito a função anônima em si.Não há nenhuma chance de, acidentalmente, a adição de variáveis de escopo global.

Isto implica que, ao utilizar o segundo método, você não está atravancando o global de variáveis de escopo, que é boa como essas global de valores de variável pode interferir com algumas outras variáveis globais que você pode usar em alguma outra biblioteca ou estão sendo usados em uma biblioteca de terceiros.

Exemplo:

<html>
<body>
<script type="text/javascript">

new function() { 
a = "Hello";
alert(a + " Inside Function");
};

alert(a + " Outside Function");

(function() { 
var b = "World";
alert(b + " Inside Function");
})();

alert(b + " Outside Function");
</script>
</body>
</html>

No código acima a saída é algo como:

Olá Dentro Da Função
Olá Fora Da Função
Mundo Dentro Da Função

...em seguida, você obter um erro como 'b' não está definido fora da função!

Assim, acredito que o segundo método é melhor...mais seguro!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top