eval
====

Resumen
-------

La función `eval()` evalúa un código JavaScript representado como una cadena de caracteres (string), sin referenciar a un objeto en particular.

Sintaxis
--------


```js
eval(cadena de caracteres o string)
```

### Parámetros

`cadena de caracteres (string)`

Una cadena de caracteres (string) que representa una expresión, sentencia o secuencia de sentencias en JavaScript. La expresión puede incluir variables y propiedades de objetos existentes.

### Valores retornados o devueltos

El valor que resulta de la evaluación del código proporcionado. Si este valor está vacío. `undefined` (artículo en inglés) es devuelto.

Descripción
-----------

`eval()` es una propiedad de la función del objeto global.

El argumento de la función `eval` es una cadena de caracteres. Si la cadena de caracteres representa una expresión, `eval()` evalúa la expresión. Si el argumento representa una o más sentencias JavaScript, `eval()` evalúa las sentencias. No se debe llamar a `eval()` para evaluar una expresión aritmética; ya que JavaScript evalúa las expresiones aritméticas automáticamente.

Si construye una expresión aritmética como una cadena de caracteres, puede usar `eval()` para evaluarla más tarde. Por ejemplo, suponga que tiene la variable `x`. Puede posponer la evaluación de una expresión que involucre a `x` mediante la asignación del valor de la cadena de caracteres de la expresión, asignando "`3 * x + 2`" a la variable, y entonces llamar a `eval()` posteriormente en el script.

Si el argumento de `eval()` no es una cadena de caracteres, `eval()` devuelve el argumento sin cambio. En el siguiente ejemplo, el constructor `String` es especificado, y `eval()` devuelve un objeto `String` en lugar de evaluar la cadena de caracteres.
```

eval(new String("2 + 2")); // devuelve un objeto String que contiene "2 + 2"
eval("2 + 2");             // devuelve 4
```


Puede trabajar sobre esta limitación de una manera genérica utilizando `toString()`.
```

var expresion = new String("2 + 2");
eval(expresion.toString());
```


Si utiliza la función `eval()` *indirectamente*, invocándola a través de una referencia distinta de `eval`, a partir de ECMAScript 5, ésta funciona en el ámbito global en lugar de hacerlo en el ámbito local; esto quiere decir, por ejemplo, que las declaraciones de función crean funciones globales, y que el código siendo evaluado no tiene acceso a las variables locales dentro del ámbito en donde está siendo llamada.


```js
function test() {
  var x = 2,
    y = 4;
  console.log(eval("x + y")); // Llamada directa, utiliza el ámbito local, el resultado es 6
  var geval = eval;
  console.log(geval("x + y")); // Llamada indirecta, utiliza el ámbito global, através de ReferenceError por que `x` es indefinida
}
```

No utilice `eval` innecesariamente
----------------------------------

`eval()` es una función peligrosa, quel ejecuta el código el cual es pasado con los privilegios de quien llama. Si ejecuta `eval()` con una cadena de caracteres que podría ser afectada por un elemento malicioso, podría terminar ejecutando código malicioso dentro de la computadora del usuario con los permisos de su página o extensión web . Más importante aún, una parte del código de terceros podría accesar al ámbito en el cual `eval()` fue invocada, lo que puede permitir la entrada a posibles ataques de formas a las que el constructor `Function` (art. en inglés) el cual es similar, no es susceptible.

`eval()` es generalmente también más lenta que otras alternativas desde que se invoca en el intérprte de JS, mientras que otros muchos constructores son optimizados por los motores JS modernos.

Existen alternativas más seguras (y rápidas) que `eval()` para casos de uso común.

### Accediendo a propiedades de los miembros

No debería utilizar `eval()` con el fin de convertir nombres de propiedades en propiedades. Observe el siguiente ejemplo en el cual la función `getNombreCampo(n)` devuelve el nombre del elemento del formulario especificado como una cadena. La primera sentencia asigna el valor de cadena del tercer elemento del formulario a la variable `campo`. La segunda sentencia utiliza `eval` para mostrar el valor del elemento del formulario.
```

var campo = getNombreCampo(3);
document.write("El campo llamado ", campo, " tiene un valor de ", eval(campo + ".value"));
```


Sin embargo, `eval()` no es necesario en este código. De hecho, su uso aquí no se recomienda. En su lugar, utilice los operadores de miembro (art. en inglés), que son mucho más rápidos y seguros:


```js
var campo = getFieldName(3);
document.write("El campo llamado ", campo, " tiene un valor de ", campo[valor]);
```


Considere ahora este nuevo ejemplo, en donde la propiedad del objeto a ser accesado no es conocida hasta que el código es ejecutado. Esto puede hacerse con eval:


```js
var obj = { a: 20, b: 30 };
var nombreProp = obtenerNombreProp(); // devuelve "a" o "b"

eval("var resultado = obj." + nombreProp);
```


Y con el uso de los accesores de propiedades (artículo en inglés), el cual es mucho más rápido y seguro, sería así:


```js
var obj = { a: 20, b: 30 };
var nombreProp = obtenerNombreProp(); // devuelve "a" o "b"
var resultado = obj[nombreProp]; // obj[ "a" ] es el mismo que obj.a
```


Puede incluso utilizar este método para acceder a las propiedades de los descendientes. Utilizando `eval()` esto sería de la siguiente forma:


```js
var obj = { a: { b: { c: 0 } } };
var propPath = getPropPath(); // returns e.g. "a.b.c"

eval("var result = obj." + propPath);
```


Evitando `eval()`, esto podría hacerse dividiendo la ruta de propiedad y haciendo un bucle a través de las diferentes propiedades:


```js
function getDescendantProp(obj, desc) {
  var arr = desc.split(".");
  while (arr.length) {
    obj = obj[arr.shift()];
  }
  return obj;
}

var obj = { a: { b: { c: 0 } } };
var propPath = getPropPath(); // returns e.g. "a.b.c"
var result = getDescendantProp(obj, propPath);
```


Estableciendo una propiedad que funcione de modo similar:


```js
function setDescendantProp(obj, desc, value) {
  var arr = desc.split(".");
  while (arr.length > 1) {
    obj = obj[arr.shift()];
  }
  obj[arr[0]] = value;
}

var obj = { a: { b: { c: 0 } } };
var propPath = getPropPath(); // returns e.g. "a.b.c"
var result = setDescendantProp(obj, propPath, 1); // test.a.b.c will now be 1
```

### Utilice funciones en lugar de evaluar fragmentos de código

JavaScript tiene funciones de primera clase(artículo en inglés), lo que quiere decir que usted puede pasar funciones como argumentos a otras APIs, almacenarlas en variables y propiedades de objetos, etc. Muchas APIs de DOM están diseñadas con esto en mente, o sea que usted puede (y debería) escribir:


```js
// instead of setTimeout(" ... ", 1000) use:
setTimeout(function() { ... }, 1000);

// instead of elt.setAttribute("onclick", "...") use:
elt.addEventListener("click", function() { ... } , false);
```


Las clausuras o cierres(art. en inglés) son muy útiles como forma de crear funciones parametrizadas sin la concatenación de cadenas de caracteres o strings.

### Analizando JSON (convirtiendo cadenas de caracteres (strings) hacia objetos de JavaScript)

Si la cadena de caracteres que usted esta llamando `eval()` contiene datos (por ejemplo, un array: `"[1, 2, 3]"`), en contraposición al código, debería considerar un cambio a JSON (art. en inglés), el cual permite a la cadena de caracteres utilizar un subconjunto de sintaxis de JavaScript para representar los datos. Vea también Descargando JSON y JavaScript en extensiones (art. en inglés).

Observe, que ya que la sintaxis de JSON es limitada en comparación con la sintaxis de JavaScript, muchas literales válidas de JavaScript no serán analizadas como JSON. Por ejemplo, seguir comas no está permitido en JSON, y los nombres de propiedades (keys) en literales de objeto deben ser entrecomilladas. Asegúrese de utilizar un serializados de JSON para generar cadenas de caracteres que posteriormente sean analizadas como JSON.

### Pasar datos en lugar de código

Por ejemplo, una extensión diseñada para arrastar contenido de páginas web podría tener reglas de arrastre definidas en XPath (art. en inglés) en lugar de código JavaScript.

### Ejecutar código sin privilegos limitados

Si usted debe ejecutar código, considere ejecutarlo con privilegios reducidos. Este consejo aplica principalmente para las extensiones y las aplicaciones XUL, para lo cual puede utilizar Components.utils.evalInSandbox (art. en inglés).

Ejemplos
--------

Los siguientes ejemplos muestran el resultado usando `document.write`. En JavaScript del lado servidor, puede mostrar el mismo resultado llamando a la función `write` en vez de `document.write`.

### Utlizando `eval`

En el siguiente código, las dos sentencias que contienen `eval` devuelven 42. La primera evalúa la cadena "`x + y + 1`"; la segunda evalúa la cadena "`42`".
```

var x = 2;
var y = 39;
var z = "42";
eval("x + y + 1"); // returns 42
eval(z);           // returns 42
```

### Utilizando `eval` para evaluar una cadena de caracteres (string) como sentencias de JavaScript

El siguiente ejemplo utiliza `eval` para evaluar una cadena de caracteres `str`. Esta cadena consiste de sentencias de JavaScript que abren un diálogo `Alert` y asignan a `z` un valor de 42 si `x` es cinco, y asigna 0 a `z` en caso contrario. Cuando se ejecuta la segunda sentencia, `eval` ocasionará que estas sentencias sean ejecutadas, y también evaluará el conjunto de sentencias y devolverá que el valor es asignado a `z`.


```js
var x = 5;
var str = "if (x == 5) {alert('z is 42'); z = 42;} else z = 0; ";

document.write("<P>z es ", eval(str));
```

### La última expresión es evaluada

`eval()` devuelve el valor de la última expresión evaluada


```js
var str = "if ( a ) { 1+1; } else { 1+2; }";
var a = true;
var b = eval(str); // devuelve 2

console.log("b is : " + b);

a = false;
b = eval(str); // devuelve 3

console.log("b is : " + b);
```

### `eval` como una cadena de caracteres (string) definiendo funciones requiere "(" y ")" como prefijo y sufijo


```js
var fctStr1 = "function a() {}";
var fctStr2 = "(function a() {})";
var fct1 = eval(fctStr1); // devuelve undefined
var fct2 = eval(fctStr2); // deuelve una función
```

Especificaciones
----------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-eval-x |

Compatibilidad con navegadores
------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Vea También
-----------

* `uneval()`
* Miembros de operadores