| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Strict_mode | [Back] [Original] |
Get to know MDN better
Esta pgina ha sido traducida del ingls por la comunidad. Aprende ms y nete a la comunidad de MDN Web Docs.
A veces, vers que llaman sloppy mode modo poco riguroso al modo no estricto predeterminado. Este no es un trmino oficial, pero tenlo en cuenta, por si acaso.
El modo estricto de ECMAScript 5 es una forma de elegir una variante restringida de JavaScript, as implcitamente se deja de lado el modo poco riguroso. El modo estricto no es slo un subconjunto: intencionalmente tiene diferencia semntica del cdigo normal. Los navegadores que no admiten el modo estricto ejecutarn el cdigo con un comportamiento diferente a los que s lo soportan, por lo tanto no confes en el modo estricto sin antes hacer pruebas de sus caractersticas ms relevantes. Los modos estricto y no estricto pueden coexistir, por lo tanto el cdigo se puede transformar a modo estricto incrementalmente.
El modo estricto tiene varios cambios en la semntica normal de JavaScript:
Ve transicin a modo estricto, si deseas cambiar tu cdigo para trabajar en la variante estricta de JavaScript.
El modo estricto se aplica a un script completo o a funciones individuales. No se aplica a bloques entre corchetes {}; intentar aplicarlo en tales contextos no hace nada. Cdigo eval, cdigo Function, atributos de controladores de eventos, cadenas pasadas a setTimeout, y similares son scripts enteros, de modo que invocar modo estricto en tales contextos funciona como se espera.
Para invocar el modo estricto en todo un script, escribe exactamente "use strict"; (o 'use strict';) antes de cualquier otra expresin.
// Sintaxis del modo estricto para todo el script
"use strict";
var v = "Hola! Estoy en modo estricto para script!";
Esta sintaxis tiene un problema que ya ha afectado a cierta pgina bien conocida: no es posible concatenar ciegamente scripts conflictivos entre s. Si concatena un script en modo estricto con otro que no es, la concatenacin de ambos producir cdigo en modo estricto. Lo contrario tambin es cierto: cdigo en modo no estricto mas cdigo estricto produce cdigo que no es estricto. Concatenar scripts no produce problemas si todos estn en modo estricto (o si todos estn en modo no estricto). El problema es mezclar scripts en modo estricto con scripts en modo no estricto. Por eso se recomienda habilitar el modo estricto a nivel de funcin solamente (al menos durante el periodo de transicin de un programa).
Otra opcin es envolver el contenido completo del script en una funcin y tener esa funcin externa en modo estricto. As se elimina el problema de la concatenacin, pero entonces tienes que hacerte cargo de exportar explcitamente las variables globales fuera del mbito de la funcin.
De igual forma, para invocar el modo estricto para una funcin, escribe exactamente "use strict"; (o 'use strict';) en el cuerpo de la funcin antes de cualquier otra expresin.
function strict() {
// Sintaxis del modo estricto a nivel de funcin
"use strict";
function nested() {
return "Y yo tambin!";
}
return "Hola! Soy una funcin en modo estricto! " + nested();
}
function notStrict() {
return "Yo no soy estricto.";
}
ECMAScript 2015 introdujo mdulos y por tanto una tercera manera de entrar en el modo estricto. Todo el contenido de los mdulos de JavaScript se encuentra automticamente en modo estricto, sin necesidad de una declaracin para iniciarlo.
function strict() {
// debido a que este es un mdulo, soy estricto por omisin
}
export default strict;
El modo estricto cambia la sintaxis y el comportamiento en tiempo de ejecucin. Los cambios generalmente caen dentro de estas categoras: cambios que convierten equivocaciones en errores (como errores de sintaxis o en tiempo de ejecucin), cambios que simplifican cmo se calcula el nombre de una variable particular, cambios que simplifican el uso de eval y arguments, cambios que hacen ms fcil escribir JavaScript "seguro", y cambios que anticipan la evolucin futura de ECMAScript.
El modo estricto cambia algunos errores de sintaxis tolerados en modo no estricto y los convierte en errores. JavaScript fue diseado de modo que fuera fcil para programadores novatos, y puede haber operaciones semnticas que deberan ser errores pero son tratadas como libres de error. A veces esto sirve para solucionar el problema en el momento, pero puede crear problemas ms graves en el futuro. El modo estricto trata las equivocaciones como errores, para que se puedan descubrir y subsanar inmediatamente.
En primer lugar, el modo estricto hace imposible crear variables globales por accidente. En JavaScript no estricto, si se escribe mal una variable en una asignacin, se crear una nueva propiedad en el objeto global y el cdigo continuar "trabajando" como si nada (aunque es posible que el cdigo as escrito falle en el futuro, en concreto, en JavaScript moderno). En modo estricto, cualquier asignacin que produzca variables globales por accidente lanzar un error:
"use strict";
// Asumiendo que exista una variable global llamada mistypedVariable
mistypeVariable = 17; // esta lnea lanza un ReferenceError debido a
// una errata en el nombre de la variable
En segundo lugar, el modo estricto lanza una excepcin en asignaciones que de otro modo fallaran silenciosamente. Por ejemplo, NaN es una variable global que no puede ser asignada. En un cdigo normal, asignar a NaN no tiene efecto; el programador no recibe ningn mensaje de error. En cambio, en modo estricto, si se intenta asignar un valor a NaN, el programador recibir una excepcin. Cualquier asignacin que falle silenciosamente en cdigo normal (asignaciones a una propiedad de no escritura, asignaciones a una propiedad captadora, asignaciones a una nueva propiedad o a un objecto no extensible) lanzar una excepcin en modo estricto:
"use strict";
// Asignacin a una no-escritura global
var undefined = 5; // lanza un TypeError
var Infinity = 5; // lanza un TypeError
// Asignacin a una propiedad de no-escritura
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // lanza un TypeError
// Asignacin a una propiedad de tipo getter
var obj2 = {
get x() {
return 17;
},
};
obj2.x = 5; // lanza un TypeError
// Asignacin a una nueva propiedad en un objeto no extensible
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // lanza un TypeError
En tercer lugar, el modo estricto lanza una excepcin al intentar eliminar propiedades no eliminables (mientra que en cdigo normal el intento no tendra ningn efecto):
"use strict";
delete Object.prototype; // lanza un TypeError
En cuarto lugar, la versin de modo estricto anterior a Gecko 34 requiere que todas las propiedades nombradas en un objeto sean nicas. En cdigo normal se pueden duplicar nombres, siendo el ltimo el que determina el valor de la propiedad. Pero como el ltimo es el nico que hace algo, la duplicidad da origen a errores si el cdigo se modifica para cambiar el valor de la propiedad. Duplicar nombres de propiedades es un error de sintaxis en modo estricto.
Nota: Este ya no es el caso en ECMAScript 2015 (error 1041128).
"use strict";
var o = { p: 1, p: 2 }; // !!! error de sintaxis
En quinto lugar, el modo estricto requiere que los nombres de los parmetros de una funcin sean nicos. En cdigo normal, el ltimo argumento repetido oculta argumentos anteriores con el mismo nombre. Estos argumentos permanecen disponibles a travs de arguments[i], de modo que no son completamente inaccesibles. Aun as, esta ocultacin tiene poco sentido y es probablemente indeseable (pues puede ocultar, por ejemplo, un error al teclear una letra). Por lo tanto, en modo estricto, duplicar nombres de argumentos es un error de sintaxis:
function sum(a, a, c) {
// !!! error de sintaxis
"use strict";
return a + a + c; // incorrecto si este cdigo se ejecut
}
En sexto lugar, en modo estricto ECMAScript 5 se prohbe la notacin octal. La notacin octal no es parte de ECMAScript 5, pero est soportada en todos los navegadores al poner como prefijo un cero al nmero: 0644 == 420 y "\045" === "%". En ECMAScript 2015, el nmero octal es compatible con el prefijo de un nmero con "0o". Es decir:
var a = 0o10; // ES2015: Octal
Los programadores novatos a veces creen que un prefijo cero inicial no tiene un significado semntico, por lo que lo usan como dispositivo de alineacin, pero esto cambia el significado del nmero! Una sintaxis de cero a la izquierda para los octales rara vez es til y se puede usar por error, por lo que el modo estricto lo convierte en un error de sintaxis:
"use strict";
var sum =
015 + // !!! error de sintaxis
197 +
142;
var sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
Sptimo, el modo estricto en ECMAScript 2015 prohbe establecer propiedades en valores primitivos. La sintaxis octal rara vez es til y se puede usar equivocadamente, de modo que en modo estricto, utilizar notacin octal lanza un TypeError:
(function () {
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
})();
El modo estricto simplifica el modo en que el nombre de una variable es asignado a un variable particular en el cdigo. Muchas optimizaciones del compilador se basan en la habilidad para decir el lugar especfico en que una variable est almacenada, lo cual es crtico para una optimizacin completa del cdigo JavaScript. Algunas veces JavaScript hace que esta asignacin bsica del nombre de una variable y su valor no suceda hasta que no se est en tiempo de ejecucin. El modo estricto elimina muchos de los casos en los que esto pasa, de modo que el compilador puede optimizar mejor el cdigo que es estricto.
Primero, el modo estricto prohbe el uso de with. El problema con with es que cualquier nombre dentro del bloque pude ser asignado a una propiedad del objecto pasado como argumento, o a una variable en su mbito circundante (o incluso global), en tiempo de ejecucin: es imposible saber de antemano cul ser. El modo estricto hace que el uso de with sea un error de sintaxis, de modo que no hay oportunidad de que una variable dentro de un with se refiera a una direccin desconocida en tiempo de ejecucin:
"use strict";
var x = 17;
with (obj) {
// !!! error de sintaxis
// Si este no estuviera un modo estricto, sera var x?, o
// sera obj.x en su lugar? Es imposible en general
// decirlo sin ejecutar el cdigo, por lo que el nombre no
// se puede optimizar.
x;
}
En vez de usar with, existe la simple alternativa de asignar el objecto a una variable de nombre ms corto, y despus acceder a la propiedad correspondiente de esa variable.
Segundo, el uso de eval en modo estricto no introduce nuevas variables en el mbito circundante. En cdigo normal, eval("var x;") introduce una variable x dentro de la funcin circundante o el mbito global. Esto significa que, en general, en una funcin que contiene una llamada a eval en cada nombre que no se refiera a un argumento o a una variable local, se debe asignar a una definicin en particular en tiempo de ejecucin (debido a que eval puedo haber introducido una nueva variable que podra ocultar una variable externa). En modo estricto, eval crea variables solo para el cdigo que se est evaluando, por lo que eval no puede afectar si un nombre se refiere a una variable externa o a alguna variable local:
var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
console.assert(x === 17);
console.assert(evalX === 42);
En el ejemplo anterior, si la funcin eval es invocada por una expresin de la forma eval(...) en cdigo de modo estricto, el cdigo ser evaluado en modo estricto. El cdigo puede explcitamente invocar el modo estricto, pero no es necesario.
function strict1(str) {
"use strict";
return eval(str); // str ser tratado como cdigo de modo estricto
}
function strict2(f, str) {
"use strict";
return f(str); // no eval(...): str es estricto si y solo
// si invoca el modo estricto
}
function nonstrict(str) {
return eval(str); // str es estricto si y solo
// si invoca el modo estricto
}
strict1("'Cdigo en modo estricto!'");
strict1("'use strict'; 'Cdigo en modo estricto!'");
estricto2(eval, "'Cdigo no estricto'");
strict2(eval, "'use strict'; 'Cdigo en modo estricto!'");
nonstrict("'Cdigo no estricto'");
nonstrict("'use strict'; 'Cdigo en modo estricto!'");
As los nombres en modo estricto usando eval se comportan idnticamente a los nombres en modo estricto no siendo evaluados como resultado de eval.
Tercero, el modo estricto prohbe eliminar nombres planos. De este modo, delete name produce un error de sintaxis.
"use strict";
var x;
delete x; // !!! error de sintaxis
eval("var y; delete y;"); // !!! error de sintaxis
eval y arguments ms simplesEl modo estricto hace que el uso de arguments y eval sea ms intuitivo. Ambos envuelven un considerable misticismo en cdigo normal: eval al aadir o remover los enlaces y cambiar los valores de dichos enlaces, y arguments al poder sustituir los nombres de los argumentos por propiedades indexadas. El modo estricto ofrece un gran paso al tratar a eval y a arguments como palabras clave, aunque soluciones finales no estarn disponibles hasta futuras ediciones de ECMAScript.
Primero, las palabras eval y arguments no se pueden ligar o asignar en la sintaxis del lenguaje. Cualquier intento producir un error de sintaxis:
"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) {} };
var eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
var y = function eval() {};
var f = new Function("arguments", "'use strict'; return 17;");
Segundo, el modo estricto no permite usar alias en elementos del objecto arguments creados dentro de la funcin. En una funcin en cdigo normal cuyo primer parmetro sea args, si se cambia el valor de args tambin se cambiar de arguments[0], y viceversa (a menos que no se proporcionen parmetros o se elimine arguments[0]). El objecto arguments para el modo estricto almacena los parmetros originales cuando la funcin es invocada. arguments[i] no guarda el valor del correspondiente nombre del parmetro, ni tampoco un parmetro con nombre guarda el valor correspondiente de arguments[i].
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
Tercero, arguments.callee no est soportado. En cdigo normal, arguments.callee se refiere a la funcin envolvente. Este caso de uso es dbil: simplemente nombra la funcin envolvente!. Adems arguments.callee merma el desempeo de funciones en lnea pues debe ser posible proveer la referencia de la funcin que llam a la funcin original cada vez que se usa arguments.callee. arguments.callee en modo estricto es una propiedad no eliminable y lanza una excepcin cuando se le asigna un valor o se intenta regresar su valor.
"use strict";
var f = function () {
return arguments.callee;
};
f(); // lanza un TypeError
El modo estricto hace ms fcil el escribir cdigo "seguro" en JavaScript. Algunos sitios web ofrecen ahora medios para que los usuarios codifiquen en JavaScript para que el cdigo corra en el sitio en beneficio de otros usuarios. JavaScript en los navegadores puede acceder a la informacin privada del usuario, por lo que dicho JavaScript se debe transformar parcialmente antes de ejecutarse, para censurar el acceso a funciones prohibidas. La flexibilidad de JavaScript hace que efectivamente sea imposible hacer esto sin muchas comprobaciones en tiempo de ejecucin. La flexibilidad de JavaScript hace casi imposible hacer esto sin hacer revisiones en tiempo de ejecucin. Unos pocos ajustes del modo estricto, adems de requerir que el JavaScript enviado por el usuario sea cdigo de modo estricto y que se invoque de cierta manera, reducen sustancialmente la necesidad de esas comprobaciones en tiempo de ejecucin.
Primero, el valor this pasado a una funcin en modo estricto no forzosamente debe ser un objeto (es decir, "empaquetado"). Para una funcin normal, this siempre es un objeto: o el objeto proporcionado si se llama con un this con valor de objeto; el valor, empaquetado, si se llama con un booleano, una cadena o un nmero this; o el objeto global si se llama con un undefined o null this. (Usar call, apply, o bind para especificar un valor del this particular). Este empaquetado automtico al pasar valores a una funcin tiene un costo en el rendimiento; no solo eso, si no que al exponer el objeto global en los navegadores es un riesgo de seguridad, debido a que el objeto global provee acceso a una funcionalidad que el cdigo de JavaScript "seguro" debe restringir. As, en una funcin en modo estricto , el valor de this no est empaquetado dentro de un objecto, y si no se especifica, this toma el valor de undefined.
"use strict";
function fun() {
return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
Esto significa, entre otras cosas, que en los navegadores no es posible hacer referencia al objeto window a travs de this dentro de una funcin en modo estricto.
Segundo, en modo estricto ya no es posible "recorrer" la pila de JavaScript a travs de extensiones de ECMAScript. En cdigo normal con estas extensiones, cuando una funcin llamada fun est en medio de su ejecucin, fun.caller es la funcin que ms recientemente llam a fun, y fun.arguments son los parmetros para esa invocacin de fun. Ambas extensiones son problemticas para JavaScript "seguro", debido a que permiten acceder a funciones "privilegiadas" y sus (potencialmente inseguros) argumentos. Si fun est en modo estricto, tanto fun.caller como fun.arguments son propiedades no eliminables que lanzan una excepcin cuando se establecen o recuperan:
function restricted() {
"use strict";
restricted.caller; // lanza un TypeError
restricted.arguments; // lanza un TypeError
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
Tercero, en funciones de modo estricto, el objeto arguments no provee acceso a las variables usadas al llamar a la funcin. En algunas implementaciones antiguas de ECMAScript, arguments.caller era un objeto cuyas propiedades apuntaban a las variables en la funcin. Esto es una amenaza de seguridad por que rompe la habilidad de ocultar valores privilegiados a travs de la abstraccin de la funcin; adems, frena algunas optimizaciones. Por estas razones los navegadores modernos no la implementan. Por su funcionalidad a lo largo de los aos, arguments.caller en una funcin de modo estricto es una propiedad que lanza una excepcin cuando se usa.
"use strict";
function fun(a, b) {
"use strict";
var v = 12;
return arguments.caller; // lanza un TypeError
}
fun(1, 2); // no expone v (o a o b)
Las futuras versiones de ECMAScript introducirn nuevos cambios, y el modo estricto en ECMAScript 5 aplica algunos de esos cambios para hacer una transicin ms suave. Ser ms fcil hacer cambios si las bases de esos cambios son prohibidas en modo estricto.
Primero, en modo estricto una lista de identificadores se convierte en palabras reservadas. Estas palabras son implements, interface, let, package, private, protected, public, static, y yield. De modo que en modo estricto, no se pueden usar estas palabras para nombrar variables o argumentos.
function package(protected) {
// !!!
"use strict";
var implements; // !!!
// !!!
interface: while (true) {
break interface; // !!!
}
function private() {} // !!!
}
function fun(static) {
"use strict";
} // !!!
Dos advertencias especficas de Mozilla: Primero, si tu cdigo esta escrito en JavaScript 1.7 o mayor (por ejemplo en cdigo chrome o cuando se usa bien <script type="">) y el cdigo esta en modo estricto, let y yield tienen la funcionalidad que han tenido desde que esas palabras clave se introdujeron por primera vez. Pero el cdigo en modo estricto en la web, cargado con <script src=""> o <script>...</script>, no podr usar let/yield como identificadores. Segundo, mientras que ES5 incondicionalmente reserva las palabras class, enum, export, extends, import y super, Mozilla Firefox 5 solo las reserva en modo estricto.
En segundo lugar, el modo estricto prohbe las declaraciones de funcin, no en el nivel superior de un script o funcin. En el modo normal de los navegadores, las declaraciones de funcin se permiten "en todas partes". Esto no es parte de ES5 (ni siquiera de ES3)! Es una extensin con semntica incompatible en diferentes navegadores. Ten en cuenta que en ES2015 se permiten declaraciones de funcin fuera del nivel superior.
"use strict";
if (true) {
function f() {} // !!! error de sintaxis
f();
}
for (var i = 0; i < 5; i++) {
function f2() {} // !!! error de sintaxis
f2();
}
function baz() {
// legal
function eit() {} // tambin legal
}
Esta prohibicin no es el modo estricto propiamente dicho porque tales declaraciones de funcin son una extensin de ES5 bsico. Pero es la recomendacin del comit ECMAScript y los navegadores la implementarn.
La mayora de los navegadores ya implementan el modo estricto. Sin embargo, no dependas ciegamente de l, ya que todava hay numerosas Versiones del navegador utilizadas en la naturaleza que solo tienen soporte parcial para el modo estricto o no lo admiten en absoluto (por ejemplo, Internet Explorer por debajo de la versin 10). El modo estricto cambia la semntica. Depender de esos cambios provocar equivocaciones y errores en los navegadores que no implementan el modo estricto. Ten cuidado al usar el modo estricto y respalda la dependencia del modo estricto con pruebas de funciones que comprueben si se implementan las partes relevantes del modo estricto. Finalmente, asegrate de probar tu cdigo en navegadores que admitan y no admitan el modo estricto. Si realizas tus pruebas solo en navegadores que no admiten el modo estricto, es muy probable que tengas problemas en los navegadores que s lo hacen, y viceversa.
| Specification |
|---|
| ECMAScript 2027 LanguageSpecification |
This page was last modified on 29 may 2026 by MDN contributors.
Your blueprint for a better internet.
Portions of this content are 19982026 by individual mozilla.org contributors. Content available under a Creative Commons license.
| Web Proxy Viewer | New URL | Original Page |