False assumption

You may have heard :

“Like in Python : everything in JavaScript is an Object”

→ ☹ WRONG ! … for Python it’s true (and for Ruby too), but not for javascript. No it’s a bit more complex for JS.

Javascript types

There are 7 types, and object has 5 differents kinds :

  • Number
    • ! ATTENTION ! : may be NaN (Not a Number)
  • String
  • Symbol (new in ES6)
  • Boolean
  • Null
  • Undefined
  • Object
    • Function
    • Array
    • Date
    • Error
    • RegExp

So Number, String, Symbol, Boolean are not object. They are primitives and undefined and null are special case✶. In fact javascript use coercion : underneath primitive usage the JS engine create and use an object (the primitive wrapper object) to return the result; then the object is throw away by Garbage Collector.

Primitive are immutable : when changing a string the JS engine will generate a new one and trhow away the old string. As explained here :

// Using a string method doesn't mutate the string
var bar = "baz";
console.log(bar);               // baz
bar.toUpperCase();
console.log(bar);               // baz

// Using an array method mutates the array
var foo = [];
console.log(foo);               // []
foo.push("plugh");
console.log(foo);               // ["plugh"]

// Assignment gives the primitive a new (not a mutated) value
bar = bar.toUpperCase();       // BAZ

✶: undefined and null are primitives but they don’t have object wrapper with valueOf() method

For more details on the internal mechanism, see the (as usual) great Todd Motto post : Understanding JavaScript types and reliable type checking

All object in JS at MDN

Null vs undefined

Null and undefined are both Primitives, difference is subtle :

  • Null = no value or an unknown value
  • undefined = unknown variable or even declared
// Using an array with only one value
// Accessing a value out of bound array will return undefined
var bar = [null];
console.log(bar[0]);       // null
console.log(bar[1]);       // undefined

// But you can also do this :
bar[1] = undefined;
console.log(bar[1]);       // undefined
// So there is no difference between a variable set to undefined
// and an undeclared variable

Note: It’s better to avoid setting variable to undefined, use null instead.

To apply a default parameter to a function (in ES5) you can check for undefined (default parameter will be part of ES6)

// Print hello or the arg string
// By default print 'hello'
var printHello(hello) {
  // Apply default parameter
  if (undefined === typeof hello) {
    hello = 'Hello';
  }
  alert(hello);
}

Typeof operator madness

Javascript typeof operator is certainly one of the most weird thing in the langage

typeof [];         // object ( → to check for array, use something else ! )
typeof {};         // object
typeof '';         // string
typeof null;       // object ( → What!? )
typeof undefined;  // undefined
typeof new Date()  // object
typeof 1;          // number
typeof function () {};// function
typeof /test/i;    // object
typeof true;       // boolean

So typeof is very dangerous : don’t use typeof everywhere. Use typeof for checking :

  • undefined
  • boolean
  • number

And for other case :

→ if browser don’t have support for this apply a simple monkey patch :

if (!Array.isArray) {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) == '[object Array]';
  };
}
  • For function use this :
var is_func = function(func_to_check)
{
  var test_obj = {};
  return func_to_check && test_obj.toString.call(func_to_check) === '[object Function]';
};
  • For null use strict (===) equals or inequals (!==) :
if (null !== foo)
  console.log('foo is not null');
if (null === foo)
  console.log('foo is null !');

Or replace Typeof by a lib that do the job

I suggest to use axis.js, very small and simple (thanks to Todd Motto).

Or a more complete one (check also DOM window.Object ect) : is.js