Pre-ES6
ES51995 – 2014One function scope, one binding keyword, and callbacks all the way down. Everything that came later is a reaction to this era's sharp edges.
`'use strict'` opts out of the most surprising legacy coercions: in sloppy mode a bare `this` is coerced to the global object, in strict mode it stays `undefined`. Modules and class bodies are strict with no opt-out.
// new Function builds a fresh function body — the directive lands first there,
// so sloppy and strict behavior can be compared side by side.
const sloppy = new Function("return this;");
const strict = new Function('"use strict"; return this;');
console.log("sloppy this:", sloppy() === globalThis ? "globalThis" : typeof sloppy());
console.log("strict this:", strict()); // stays undefined — no global coercion
// Class bodies are strict regardless of the surrounding file:
class Probe {
whoAmI() {
return this;
}
}
console.log("class method, this=undefined:", new Probe().whoAmI.call(undefined));| V8 | Classic scripts stay sloppy unless a `"use strict"` directive opens the file; modules and class bodies are strict with no opt-out. |
|---|---|
| Node.js | CommonJS files are sloppy unless the directive is present; `.mjs` and `"type": "module"` files are always strict. |
| Deno | Strict everywhere — every file is an ESM module, so sloppy-mode coercions from old demos cannot happen at all. |
| Bun | Matches Node's split: CJS is sloppy by default, ESM is strict, and `"use strict"` still works as an escape hatch inside CJS. |