Javascript's Slightly Stricter Mode

A confession

I am not really a Javascript developer

Goodfilms

Coffeescript

When did I start using it?

"use strict";

Yeoman generated it for me.

This talk is now:

Glen didn't know about Javascript

mildly interesting

strict mode

Bugs

Strict mode fixes

didn't know existed

# rubby.rb
a = "foo"
# cahfee.coffee
a = "foo"
//lolscript.js
var a = "foo";
var a = Math.PI;
console.log(a);
// 3.14159...
var a = Math.PI
console.log(a)
// 3.14159...
a = Math.PI
console.log(a)
// 3.14159...
function someSetup() {
  a = Math.PI;
}
someSetup();
console.log(a);
// 3.14159...

Non-strict mode

Strict mode

function someSetup() {
  a = Math.PI;
}
someSetup();
console.log(a);
// 3.14159...
"use strict";
function someSetup() {
  a = Math.PI; // BOOM!
}
someSetup();
console.log(a);

throws ReferenceError

"Strict mode forbids implicit creation of global property 'a'"

Non-strict mode

YOLO mode

Strict mode

function someSetup() {
  a = Math.PI;
}
someSetup();
console.log(a);
// 3.14159...
"use strict";
function someSetup() {
  var a = Math.PI;
}
someSetup();
console.log(a); // BOOM!

throws ReferenceError

"Can't find variable: a"

removes some lols

makes code faster

changes important stuff

YOLO mode

var eval, arguments;
eval = 010;
delete eval;
arguments = {x: 1, x: eval}
function y(a, a) {
  return a;
}
console.log(y(null, arguments.x));
// 8

Strict mode

"use strict";
var eval, arguments;        // keywords as vars BOOM
eval = 010;                 // octals BOOM
delete eval;                // deleting locals BOOM
arguments = {x: 1, x: eval} // duplicate key BOOM
function y(a, a) {          // duplicate argument BOOM
  return a;
}

Syntax Error

"Parse error"

Stop the lols!

Performance?

YOLO mode

Strict mode

var a = {x: 1, y: 2};
var x = 3;
with (a) {
  console.log(x);
}
// 1
"use strict";
var a = {x: 1, y: 2};
var x = 3;
with (a) { // BOOM!
  console.log(x);
}

Syntax Error

"Parse error"

YOLO mode

Strict mode

function y() {
  var me = arguments.callee;
  return me.name +
         " <- " +
         me.caller.name;
};
function x() {
  return y();
}
console.log(x());
// "y <- x"
"use strict";
function y() { // BOOM ☟
  var me = arguments.callee;
  return me.name +
         " <- " +
         me.caller.name;
};
function x() {
  return y();
}
console.log(x());
Note: Function.caller can do
most of the same things anyway

Type Error

"Unable to access callee of strict mode function"

Serious time

Semantic changes

Implicit global this

function x(a) {
  this.a = a;
};

// Calling a function:
x("foo");
// is equivalent to:
x.call(window, "foo");
// so window.a = "foo";
"use strict";
function x(a) {
  this.a = a; //BOOM!
};

// Calling a function:
x("foo");
// is equivalent to:
x.call(undefined, "foo");

this becomes window

this becomes undefined

var whatIsThis;
(function() {
  whatIsThis = function() {
    return this;
  };
})();
(function() {
  "use strict";
  console.log(whatIsThis());
})();
// window
var whatIsThis;
(function() {
  "use strict";
  whatIsThis = function() {
    return this;
  };
})();
(function() {
  console.log(whatIsThis());
})();
// undefined

Strict Mode invocation
of YOLO function

Strict Mode declaration
YOLO invocation

Evals

var a = 1, b = 2;
eval("a = 'foo';");
eval("var b = 'bar';");
eval("var c = 'baz';");
console.log(a); // 'foo'
console.log(b); // 'bar'
console.log(c); // 'baz'
"use strict";
var a = 1, b = 2;
eval("a = 'foo';");
eval("var b = 'bar';");
eval("var c = 'baz';");
console.log(a); // 'foo'
console.log(b); // 2
console.log(c); // BOOM!

Eval'd code getting all
up in yo' business  ✖

Eval'd code evaluated
in its own scope  ✔

Javascript code

was written YOLO

break if interpreted as strict.

Strict Mode is ignored

older browsers

Be safe

Concatenation

// file1.js
"use strict";
(function() {
  // do some rad stuff
})();

// file2.js
jQuery.trolol...
// file1.js
jQuery.trolol...

// file2.js
"use strict";
(function() {
  // do some rad stuff
})();

Other code interpreted
as Strict  ✖

Your code is
no longer Strict  ✖

// file1.js
(function() {
  "use strict";
  // do some rad stuff
})();

// file2.js
jQuery.trolol...
// file1.js
jQuery.trolol...

// file2.js
(function() {
  "use strict";
  // do some rad stuff
})();

Your code strict  ✔
Other code unchanged  ✔

Other code unchanged  ✔
Your code Strict  ✔

Wrap every file

// safe.js
(function() {
  "use strict";
  
  // go bananas.
  
})();

Wrap every file

IIFE

Strict Mode enabled

CoffeeScript is awesome

but it won't teach you Javascript

Thank You!

http://github.com/geelen/web-directions-talk

@glenmaddern