JavaScript OMG! #6 to #10

The Blurb: This is mostly just a bit of fun and in form of some rough notes as I’ve been sticking my head into a few JavaScript books and thought I’d write down what strikes me as odd/interesting along the way. Of course, I’ve written some bits of JavaScript but I’ve never really sat down and read up on it. I’m not trying to be definitive and nor am I trying to take a particular view – just poking around Smile

OMG #6 – The Global Object

You’ll think I’m an idiot (fair comment Smile) but I’d no idea that when I was working with JavaScript and defining global variables and global functions and so on that I was actually mutating the global object. I’d never appreciated that there was a global object and so I’d been living in a place of ignorance and so now I know (or at least I think I do) that when I’m writing;

var myVariable = "some value";

// this

// is just like this

// is just like this

// and this is true
console.log("myVariable" in this);

then I’ve more of an appreciation that what I’m doing is adding to the properties of the global object which I can reach via its this reference.

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 42

OMG #7 – “Expando Objects”

JavaScript has the very powerful/scary system which allows you to just expand objects with new properties as/when you feel like it unless those objects have been marked to disallow it. So, I can just go ahead and make myself a new object and then start to add things to it;

var myObject = { };

// just add whatever I want to this thing...
myObject.x = 10;
myObject.y = 20;
myObject.add = function() { return(this.x + this.y); }


// arrays are also objects
var myArray = [1,2,3];
myArray.sum = function()
  // no attempt to require numbers here.
  var sum = 0;
  for (var i = 0; i < this.length; i++) 
    sum += this[i];


// functions are also objects
var square = function(x) 
      return(x * x);
square.y = 100;

console.log(square.y + square(5));

This is all a little bit mind-blowing and it’s hard to thing of anything similar in the .NET world although there are ExpandoObject types that might get you somewhere near to it and especially when coupled with dynamic in C# 5;

      dynamic expando = new ExpandoObject();
      expando.x = 10;
      expando.y = 10;
      expando.Add = new Func<int>(() => expando.x + expando.y);

      // can't really do the array/function variant in the same spirit
      // I don't think...

I suspect that this will take a little getting used to Winking smile

Reference: Flanagan, “JavaScript The Definitive Guide”

OMG #8 – Wrappers

Wrapper objects feel a little to me like the process of “boxing” in .NET. In an ideal world, it’d be nice to treat everything in an object-oriented language as an object but it’s impractical to do so for primitive types generally because your performance goes straight out of the window and so languages come up with this idea of object-when-needs-to-be like .NET has with boxing. In JavaScript, this seems to called “Wrapper Objects” and it allows me to treat a primitive like an object when I want to.

// pure primitives
var n = 1;
var s = "this is a string";
var b = false;

console.log(typeof(n)); // number
console.log(typeof(s)); // string
console.log(typeof(b)); // boolean

// wrapped primitives
var nW = new Number(1);
var sW = new String("this is a string");
var bW = new Boolean(false);

console.log(typeof(nW)); // object
console.log(typeof(sW)); // object
console.log(typeof(bW)); // object

console.log(n == nW); // true
console.log(s == sW); // true
console.log(b == bW); // true
console.log(n === nW); // false
console.log(s === sW); // false
console.log(b === bW); // false

and I guess this doesn’t really seem that different from the C# world;

      // string omitted because it's a ref type in .NET
      int n = 1;
      bool b = false;


      object nW = n;
      object nB = b;

      Console.WriteLine(nW.GetType());  // .NET still says int       
      Console.WriteLine(nB.GetType());  // .NET still says bool

      // .NET requires the explicit cast to the primitive type
      Console.WriteLine(n == (int)nW);
      Console.WriteLine(b == (bool)nB);

although that short sample does already highlight differences and, combined with OMG 7 above about “Expando Objects” I was particularly struck by the example given in Flanagan around;

var myNumber = 1;
myNumber.myProperty = "ABC"; // "box" the primitive once.
console.log(myNumber.myProperty); // "box" again, different wrapper, undefined

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 43

OMG #9 – Type Conversions

Generally speaking, I hate type conversions much as I hate precedence rules Smile I can never learn tables containing rules so for me an ideal programming language would be one that made everything explicit so I never had to learn any conversion rules or precedence rules – I’m not saying that I’m typical here Winking smile

JavaScript has a pretty complex list of type conversions that it’s prepared to bring into play on your behalf. Most of them I found pretty intuitive. The way I decided whether they were intuitive or not run down the conversion table with my finger over the results and see if I could just “guess” how it would work.

Here’s the ones that I got wrong and/or found a bit trickier to guess;

var minusZero = new String(-0);
console.log(minusZero); // logs 0, not -0

var undefinedNumber = new Number(undefined);
console.log(undefinedNumber); // logs NaN

var numbers = new Number([1]);
console.log(numbers); // this logs 1, not so surprising

numbers = new Number([1,2,3]);
console.log(numbers); // this logs NaN, a little surprising

but others did seem largely do what I’d expect them to do with the possible caveat that I’d have to remember;

var b = false;
var o = new Boolean(b);

if (o)
  console.log("a little unexpected but, true");

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 46/49.

OMG#10 – Object to Primitive Conversions

This feels like a bit of a minefield. Objects convert to booleans very naturally by converting to true for every value that’s not null or undefined so that’s easy enough to “get”.

Converting objects to strings seems simple in that it seems to go via toString() and then if that isn’t appropriate (i.e. doesn’t give some primitive value that can be converted to a string or doesn’t exist) then it goes via valueOf() to try and get to some primitive value;

var o = { x:10 };
o.toString = function() 
    return("ToString Value is " + this.x); 
// logs "ToString Value is x"

// break toString by having it return a non-primitive
o.toString = function() 
o.valueOf = function() 
    return("ValueOf Value is " + this.x); 

// logs "ValueOf Value is x"

and so that seems relatively simple as does the conversion to a number which sort of goes the other way around;

var o = { x:10 };
o.valueOf = function() 

// logs this.x ( 10 ) via valueOf

// take valueOf away
delete o.valueOf;

o.toString = function()

// allow toString to kick in
// logs "10" via toString

but then there appears to be some built-in behaviours to certain operators (e.g. +) which have their own way of working – need to do a little more digging to understand that fully.

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 50/51.

To be continued – you can find the rest of these “JavaScript OMG!!” entries here.