JavaScript

Things you should know

Created by Robbie Bardijn

Topics:

  • History (ECMA Script, Standardisations, a glance at the future)
  • Browser engines (Comparison & recap, documentation & reference)
  • Good parts (The power of JS)
  • Bad parts (Things you should NOT use)
  • JSHint (How to identfy those bad parts)
  • (BREAK)
  • Minty code (Repetition elimination, complex ifelse logic, deferreds, tenplating)

Javascript is one of the world's most popular and most hated
programming language at the same time.

Influences



  • Self
    • prototypal inheritance
    • dynamic objects
  • Java
    • syntax
    • conventions



  • Scheme
    • lambda
    • loose typing
  • Perl
    • regexp

19 years of History

1995
Invented by Brendan Eich, see in action

1996
ECMA-262, standardisation began

1997
Microsoft used JScript so ECMA script 1 had to be made

1998
ECMA script 2 followed with minor editorial changes

19 years of History

1999
ECMA script 3
Legacy browsers like ie8 use this

Unknown
ECMA script 4 abandoned due to political differences

2009
ECMA script 5
adds strict mode and adds some new features

19 years of History

18 juli, 2014 draft
ECMA script 6
Adds better code support for writing front-end apps.

Unknown
ECMA script 7
Early stage of development

Browser Rendering engines


Chrome 28+ and Opera 15+

uses Blink, a fork of webkit uses the V8 Javascript engine

Internet explorer

uses Trident that uses Chakra Jscript engine

Firefox

uses Gecko that uses Spidermonkey Javascript engine

Safari

uses Webkit2 build on top of webkit that uses JavascriptCore Javascript engine

full list

Indeed!

WTF

What can I use in browser X?

Can I use Array.forEach(callback[, thisArg])?

Can I use JSON?

Can I use Object.keys()?

The answer

Helper libraries
(jQuery, Underscorejs, requireJS)

Shims
(Es5-shim, Es6-shim)

Polyfills

The reference

ECMASCRIPT tables
(ES5, ES6)

Mozilla documentation
(js reference)

First questions?

So Javascript

Should you know everything?



No

not everything

Good parts

  • Loose typing
  • Functions
  • Expressive object literal
  • Dynamic objects
  • Function scope / closure

Loose typing




var a = 13; // Number declaration
var b = "beee"; // String declaration
var c = true; // Boolean declaration
var d = []; // Array declaration
var e = {}; // Object declaration
var f = function(){}; // Function declaration
    

Functions as first class objects

  • Instance of the Object type
  • Store in a variable
  • As a parameter to another function
  • Return a function from another function

Functions as first class objects


var myBarFunc = function test(foo) {
  foo += 1;
  return foo;
};

var getKeys = function(obj){
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
};
// consoles
// "prototype -> [object Object]"
// "length -> 1"
// "name -> test"

getKeys(myBarFunc);

    

Expressive object literal


var person = {
  firstName: "John",
  lastName: "Doe",
  gunType: "Revolver",
  sayHi: function() {
    console.log("Howdy");
  }
};
    

Dynamic objects


var person = {
  firstName: "John",
  lastName: "Doe",
  gunType: "Revolver",
  sayHi: function() {
    console.log("Howdy");
  }
};

console.log(person.firstName + " " + person.lastName); //GET
person.sayHi(); //GET
person.gunType = "Shotgun"; //SET = update key
person["shoe-type"] = "Cowboy Boots"; //Other Notation
person.fireGun = function() {
  console.log("BAM");
}; //SET = create key

person.fireGun(); //GET
delete person.fireGun; //REMOVE
    

Function scope


var foo = function() {
  var a = 3, b = 5;

  var bar = function() {
    var b = 7, c = 11;
    /// At this point, a is 3, b is 7 and c is 11

    a += b + c;
    // At this point, a is 21, b is 7 and c is 11
  };
  // At this point, a is 3, b is 7 and c is undefined

  bar();
  // At this point, a is 21, b is 5

}
    

Closure


function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + (++tmp)); // will also alert 16
  }
}

var bar = foo(2); // bar is now a closure.
bar(10);
/////////// another example ///////////

var quo = function(status) {
  return { // return an object
      get_status: function() {
      return status; // access status from outer function
    }
  }
}

var myQuo = quo("amazed");
console.log(myQuo.get_status()); // outputs amazed
    

Bad parts

  • Type coercion equality operators (FROM JAVA)
  • typeof
  • Global variables
  • Adding vs concatenating (FROM JAVA)
  • Auto semicolon insertion
  • parseInt
  • Phony arrays
  • Reserved words
  • Too many falsy values

type coercion == and !=


"" == "0" // false
0 == "" // true
0 == "0" // true
false == "false" // false
false == "0" // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true
"abc" == new String("abc") // true ANTIPATERN

// BAD
var name = object[namekey];
if (name == null) { // two errors that cancel each other out
  console.log("Name not found.");
}
// GOOD
var name = object[namekey];
if (name === undefined) {
  console.log("Name not found.");
}

    
  

typeof

      
// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // Despite being "Not-A-Number"
typeof Number(1) === 'number'; // but never use this form!


// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof always return a string
typeof String("abc") === 'string'; // but never use this form!


// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // but never use this form!

// Undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined';

// Functions
typeof function(){} === 'function';
typeof Math.sin === 'function';

// Objects
typeof {a:1} === 'object';
typeof new Date() === 'object';


// The weirdness begins
// DO NOT USE
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String("abc") === 'object';

typeof [1, 2, 4] === 'object'; // HOW DO WE TEST FOR ARRAYNESS
typeof NaN === "number" // SAY WHUT?
typeof null === "object";

      
    

Global variables

      
var foo = value; // outside of any scope
window.foo = value; // anywhere in the code
foo = value; // anywhere in the code IMPLIED GLOBAL

(function () {
    var not_a_global = 1;
    alert(not_a_global);
})();
      
    

+ Adds and concatenates

      
var a = 10;
var b = 20;
console.log("result is " + a + b);
// RESULT IS 1020

// fast solution
console.log("result is " + (a + b));
// RESULT IS 30
      
    

Auto semicolon insertion

      
// AT THE END OF A FUNCTION FOR EXAMPLE
// Style isn't subjective in JS
return
{
  status: true
};

// BECOMES
return ; //SEMICOLON INSERTION
{
  status: true;
}

// SILENT ERROR!!!

// good style example
var myFunc = function foo(par1, par2) {
  if(par2 === undefined) {

    return "par2 is undefined";
    par2 = "Ok";
  } else {

    return "par2 is defined";
  }

  return "Bar";
};

      
    

parseInt

      
/// ALL RETURN 15
parseInt(" 0xF", 16);
parseInt(" F", 16);
parseInt("17", 8);
parseInt(021, 8);
parseInt("015", 10);
parseInt(15.99, 10);
parseInt("FXX123", 16);
parseInt("1111", 2);
parseInt("15*3", 10);
parseInt("15e2", 10);
parseInt("15px", 10);
parseInt("12", 13);

parseInt("16"); // 16
parseInt("16 ton"); // 16

parseInt("0e0"); // 0
parseInt("08"); // 0, '8' is not an octal digit.
parseInt("09"); // 0, '8' is not an octal digit.
parseInt("027"); // 23
parseInt("011"); // ?
parseInt("0111"); // ? :D
      
    

Phony arrays

      
var myArray = [1, 2, 3];

//WRONG WAY
if(typeof myArray === 'array') {
  // NOT ENTERED
}

//RIGHT WAY
if(Object.prototype.toString.apply(myArray) === "[object Array]") {
  // myArray is truly an array
}
      
    

Reserved Words

break, case, class, catch, const, continue, debugger, default, delete, do, else, export, extends, finally, for, function, if, import, in, instanceof, let, new, return, super, switch, this, throw, try, typeof, var, void, while, with, yield enum, await, implements, package, protected, static, interface, private, public, abstract, boolean, byte, char, double, final, float, goto, int, long, native, short, synchronized, transient, volatile
      
var method; // Ok
var class; // Illegal
var object = {
  box: "value", // Ok
  case: "value", // Illegal
  "case": "value" // Ok
}
object.box = "another value"; // Ok
object.case = "another value"; // Illegal
object["case"] = "another value"; // Ok
      
    

false, null, undefined, NaN, 0, ""

      
false == null; // false
false == undefined; // false
false == NaN; // false
false == 0; // true
false == ""; // true

null == NaN // false
null == 0 // false
null == "" // false
null == undefined // true

undefined == NaN // false
undefined == 0 // false
undefined == "" // false

0 == "" //true
      
    

OMG! More bad parts!

  • NaN
  • Floating point
  • hasOwnProperty
  • With Statement
  • Eval is as evil as in php
  • Bitwise operators
  • Typed wrappers
  • new
  • void

JSHint NOT jslint

  • JSHint flags suspicious usage.
  • community driven npm module
  • It detects those bad parts.
  • Configuration levels
  • Build tool integration.
  • Immediate indication in editor

Installation

npm install jshint -g

Configuration

Indication

Sublime Text 3

screen

Flags


{
    "browser": true,
    "bitwise": true,
    "white": true,
    "devel": true,
    "curly": true,
    "eqeqeq": true,
    "forin": true,
    "immed": true,
    "indent": 2,
    "latedef": true,
    "newcap": true,
    "noarg": true,
    "quotmark": true,
    "regexp": true,
    "undef": true,
    "unused": true,
    "trailing": true,
    "smarttabs": true,
    "jquery": true,
    "predef": [
        "Drupal",
        "$",
        "Modernizr",
        "_",
        "bowser",
        "settings",
        "context"
    ]
}
    
  

Detecting JavaScript code smell

smell

What's the harm?




The Smell: Repetitive Code

The Fix: Functions

Smelly

Minty

Opportunity

The Smell: Repetitive Code

The Fix: Objects

Smelly

Minty

Opportunity

The Smell: Generated IDs

The Fix: Closures

Smelly

Minty

Opportunity

The Smell: Excessive ifs

The Fix: Using build in functions

Smelly

Minty

The Smell:
Async Acrobatics

The Fix: Deferreds

Smelly

Minty

Opportunity

The Smell: HTML
in Your JavaScript

The Fix: Templates

Smelly

Minty

Kitten

Thank you

Questions?


Recommended Books:

JavaScript: The Good Parts by Douglas Crockford and
JavaScript Paterns by Stoyan Stefanov and
Testable JavaScript by Mark Ethan Trostler