2012-01-29 21 views
97

Duplicar posible:
What is the (function() { })() construct in JavaScript?JavaScript avanzado: ¿Por qué esta función está entre paréntesis?

me encontré con este fragmento de código JavaScript, pero no tengo ni idea de qué hacer fuera de él. ¿Por qué obtengo "1" cuando ejecuto este código? ¿Qué es este pequeño y extraño apéndice de (1) y por qué la función está entre paréntesis?

(function(x){ 
    delete x; 
    return x; 
})(1); 
+0

Es un IIFE, detalles aquí: http://www.markupjavascript.com/2016/07/what-are-immediately-invoked-function.html –

Respuesta

208

Hay algunas cosas sucediendo aquí. En primer lugar es el immediately invoked function expression (IIFE) patrón:

(function() { 
    // Some code 
})(); 

Esto proporciona una manera de ejecutar código JavaScript en su propio ámbito. Usualmente se usa para que las variables creadas dentro de la función no afecten el alcance global. Puede usar esto en su lugar:

function foo() { 
    // Some code 
} 
foo(); 

Pero esto requiere dar un nombre a la función, que no siempre es necesario. El uso de una función nombrada también significa que en algún punto futuro la función podría volver a llamarse lo que podría no ser deseable. Al utilizar una función anónima de esta manera, se asegura de que solo se ejecute una vez.

Esta sintaxis no es válida:

function() { 
    // Some code 
}(); 

Porque hay que envolver la función en paréntesis, con el fin de hacer que analiza como una expresión. Más información está aquí: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Así que para recapitular rápidamente en el patrón IIFE:

(function() { 
    // Some code 
})(); 

permite ser ejecutado inmediatamente 'algún código', como si estuviera en línea acaba de escribir, sino también dentro de su propio ámbito para no afectar el espacio de nombres global (y así interferir o interferir con otros scripts).

Puede pasar argumentos a su función como si se tratara de una función normal, por ejemplo,

(function(x) { 
    // Some code 
})(1); 

Así que estamos pasando el valor '1' como el primer argumento de la función, que lo recibe como una variable de ámbito local, llamada x.

En segundo lugar, usted tiene las tripas del código de función en sí:

delete x; 
return x; 

El operador de eliminación eliminará las propiedades de los objetos. No elimina variables. Asi que;

var foo = {'bar':4, 'baz':5}; 
delete foo.bar; 
console.log(foo); 

resultado de esto se registra:

{'baz':5} 

Considerando que,

var foo = 4; 
delete foo; 
console.log(foo); 

registrará el valor 4, debido a foo no es una variable de una propiedad y por lo tanto no puede haber borrado

Mucha gente asume que eliminar puede eliminar variables, debido a la forma en que funcionan los autoglobals. Si se asigna a una variable sin declarar en primer lugar, que en realidad no va a ser una variable, sino una propiedad del objeto global:

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this! 
delete bar; 
console.log(bar); // Error - bar is not defined. 

Esta vez las obras de eliminación, porque no se va a eliminar una variable, pero una propiedad en el objeto global. En efecto, el fragmento anterior es equivalente a esto:

window.bar = 4; 
delete window.bar; 
console.log(window.bar); 

Y ahora se puede ver cómo es análoga al ejemplo foo objeto y no el ejemplo foo variable.

+18

¡Muy buena explicación! –

+1

Muy bien poner explicación. Además, como nota al margen, vi a Douglas Crockford mencionar en una charla que prefiere (function() {}()); envolviendo efectivamente todo el IIFE en parens para mayor claridad - más expresivo. – GuiDoody

+0

comparando con el enlace wiki, los parens están envolviendo todo, ¿hay alguna diferencia? –

9

Significa que ha creado una función anónima, y ​​lo llama con el parámetro 1.

Es lo mismo que:

function foo(x) { 
    delete x; 
    return x; 
} 
foo(1); 
+2

Usaría 'var foo = function() {} 'evitar confunde declaraciones de función y expresiones de función. – hugomg

+1

@missingno Son lo mismo. – xdazz

1

La razón por la que todavía consigue 1 devuelto es que la palabra clave de eliminación es para la eliminación de propiedades de los objetos. El resto es lo que otros han comentado, todo lo que está entre corchetes se ejecuta como una función, y el segundo conjunto de corchetes son los argumentos pasados ​​a ese bloque.

Aquí está el MDN reference for delete, y el MDN reference for closures, que analiza también las funciones anónimas.

2

Las personas normalmente llaman a estas "expresiones de funciones invocadas inmediatamente" o "funciones de autoejecución".

El objetivo de esto es que las variables declaradas dentro de esa función no se filtren al exterior.

Cuestiones relacionadas