¿Por qué necesitamos el modo estricto en JavaScript?

Convertir los errores en fallos

Los errores se convierten en fallos. Antes se aceptaban en modo no estricto. El modo estricto restringe el uso de la sintaxis de error y no dejará que el código se ejecute con errores en su lugar.

Dificulta la creación de variables globales al no dejarnos declarar variables con varlet, o const, por lo que crear variables sin declararlas con esas palabras clave no funcionará. Por ejemplo, el siguiente código lanzará un ReferenceError:

'use strict';
badVariable = 1;

No podemos ejecutar el código anterior en modo estricto porque este código creará una variable global badVariable si el modo estricto está desactivado. El modo estricto evita esto para prevenir la creación de variables globales accidentalmente.

Cualquier código que falle silenciosamente lanzará ahora una excepción. Esto incluye cualquier sintaxis no válida que antes se ignoraba silenciosamente.

Por ejemplo, no podemos no asignar a variables de sólo lectura como argumentsNaN, o eval con el modo estricto activado.

Cualquier asignación a propiedades de sólo lectura como propiedades globales no escribibles, asignación de propiedades de sólo obtención y asignación de cosas a propiedades de objetos no extensibles lanzará una excepción en modo estricto.

A continuación se muestran algunos ejemplos de sintaxis que fallarán con el modo estricto activado:

Todos los ejemplos anteriores lanzarán un TypeErrorundefined y Infinity son objetos globales no escribibles. obj es una propiedad no escribible.

obj2 La propiedad foo es una propiedad sólo obtenible, por lo que no se puede establecer. fixedObj se impidió que se le añadieran más propiedades con el método Object.preventExtensions.

También, el borrado de propiedades indelebles lanzará un TypeError cuando haya código que lo intente. Por ejemplo:

'use strict';
delete Array.prototype

Esto lanzará un TypeError.

El modo estricto también prohíbe los nombres de propiedades duplicados en un objeto antes de la introducción de ES6, por lo que el siguiente ejemplo arrojará un error de sintaxis:

'use strict';
var o = { a: 1, a: 2 };

El modo estricto requiere que los nombres de los parámetros de las funciones sean únicos. Sin el modo estricto, si dos parámetros tienen el nombre uno, entonces el definido más tarde será aceptado como el valor del parámetro cuando se pasen los argumentos.

Con el modo estricto, tener múltiples parámetros de función con el mismo nombre ya no está permitido, por lo que el siguiente ejemplo fallará al ejecutarse con un error de sintaxis:

const multiply = (x, x, y) => x*x*y;

La sintaxis octal tampoco está permitida en el modo estricto. No forma parte de la especificación, pero se admite en los navegadores anteponiendo un 0 a los números octales.

Esto confunde a los desarrolladores ya que algunos pueden pensar que el 0 que precede al número no tiene sentido. Por lo tanto, el modo estricto desestima esta sintaxis y lanzará un error de sintaxis.

El modo estricto también evita el uso de sintaxis que dificulta las optimizaciones. Necesita saber que una variable está realmente almacenada en la ubicación que cree que está almacenada antes de hacer la optimización, por lo que tenemos que evitar el tipo de sintaxis que impide que las optimizaciones ocurran.

Un ejemplo de esto es la declaración with. Si la usamos, impide que el intérprete de JavaScript sepa a qué variable o propiedad se refiere, ya que es posible tener una variable con el mismo nombre dentro o fuera de la sentencia with.

Si tenemos algo como el siguiente código:

let x = 1;
with (obj) {
x;
}

Entonces, JavaScript no sabría si el x dentro de la declaración with se refiere a la variable x o a la propiedad de objobj.x.

Por lo tanto, la ubicación en memoria de x es ambigua. Así, el modo estricto impide que se utilice la sentencia with. Si tenemos el modo estricto como el siguiente:

'use strict';
let x = 1;
with (obj) {
x;
}

Entonces el código anterior tendrá un error de sintaxis.

Otra cosa que el modo estricto impide es la declaración de variables dentro de una sentencia eval.

Por ejemplo, sin el modo estricto, eval('let x') declararía la variable x dentro del código. Esto permite a la gente ocultar declaraciones de variables en cadenas que podrían anular la misma declaración de variables que está fuera de la declaración eval.

Para evitar esto, el modo estricto desestima las declaraciones de variables en el argumento de la cadena que pasamos a una sentencia eval.

El modo estricto también prohíbe la eliminación de nombres de variables simples, por lo que lo siguiente arrojará un error de sintaxis:

'use strict';
let x;
delete x;