Strict Mode

Making JS less bad

Mike Sherov

Sloppy Mode Expert

Zen

Overview

  • Converting Mistakes Into Errors
  • Simplifying variable use
  • Fixing eval and arguments
  • Securing JS
  • Future proofing

Converting Mistakes Into Errors

'use strict';
var mistypedVariable;                       
mistypeVariable = 17; // ReferenceError
'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
'use strict';
delete Object.prototype; // throws a TypeError

Converting Mistakes Into Errors

function sum(a, a, c) { // !!! syntax error
  'use strict';
  return a + a + c; // wrong if this code ran
}
// before strict mode:
0644 === 420 // accidental octal literals!
var a = 0o10; // ES2015: Octal literals!
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

Simplifying Variable Usage

'use strict';
var x = 17;
with (obj) { // !!! syntax error
  // If this weren't strict mode, would this be 
  // var x, or would it instead be obj.x?  It's 
  // impossible in general to say without running
  // the code, so the name can't be optimized.
  x;
}
var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");
console.assert(x === 17);
console.assert(evalX === 42);
'use strict';

var x;
delete x; // !!! syntax error

eval('var y; delete y;'); // !!! syntax error

Making eval and arguments Simpler

'use strict';
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
'use strict';
var f = function() { return arguments.callee; };
f(); // throws a TypeError

Securing JS

'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);
function restricted() {
  'use strict';
  restricted.caller;    // throws a TypeError
  restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
  return restricted();
}
privilegedInvoker();

Future Proofing

function package(protected) { // !!!
  'use strict';
  var implements; // !!!

  interface: // !!!
  while (true) {
    break interface; // !!!
  }

  function private() { } // !!!
}
function fun(static) { 'use strict'; } // !!!

// implements, interface, let, package, private, 
// protected, public, static, and yield
'use strict';
if (true) {
  function f() { } // !!! syntax error
  f();
}

for (var i = 0; i < 5; i++) {
  function f2() { } // !!! syntax error
  f2();
}

Example

Comments?

Questions?

Strict Mode

By mikesherov

Strict Mode

  • 1,452