JavaScript OMG #26 to #30

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 #26 – Partial Application & Mapping

Nothing radical in this OMG, it’s really one for me to remember to try to “think functionally” and that came home while reading about map and partial application which I’ve tried to do here via ES5’s bind function;

// I can write a function map which performs some function on
// every array element.
function map(func, array) {

  var result = [];

  for (var i = 0; i < array.length; i++) {

    result.push(func(array[i])); // func may well see "undefined".
  }
  return (result);
}

// I can then "bind" a version of that function such that its invocation context
// and first parameter are hard-wired
var squareMap = map.bind(null, function (x) { return (x * x); });

// And then apply that to some array of values.
console.log(squareMap([1, 2, 3])); // logs 1, 4, 9

// And then move up a level with an array of arrays
console.log(map(squareMap, [[1, 2, 3], [4, 5, 6], [7, 8, 9]])); // logs 1,4,9....

Reference: Haverbeke, “Eloquent JavaScript” Page 90-91

OMG #27 – “Self Defining” Functions

This one came from a discussion with my legendary colleague Mike Ormond where we were talking about doing something simple like having a unique object key stored in each object of a particular type.

You start off with something like;

var MyType = (function () {

  var sharedId = 0;

  var ctor = function () {
    this.id = sharedId++;
  };

  return (ctor);

})();

var one = new MyType();
console.log(one.id);
console.log(one.id);
var two = new MyType();
console.log(two.id);

and then I wonder if I can hide the id so it isn’t a straight property that can be changed by someone assigning a new value to it for instance and so I hide it behind a function;

var MyType = (function () {

  var sharedId = 0;

  var ctor = function () {

    var localId = sharedId++;

    this.id = function () {
      return (localId);
    };
  };

  return (ctor);

})();

var one = new MyType();
console.log(one.id());
console.log(one.id());
var two = new MyType();
console.log(two.id());

Now, someone can still delete the id() function but my next thought was that it seems wasteful for every instance to have to have a different function just to get its id. Isn’t this where the prototype should help out? Couldn’t it take the burden of implementing that function?

To be honest, I think the answer is “no”. The prototype is shared between every instance and I’m looking for a piece of state which is unique to the instance so it feels like the only route left feels to be;

var MyType = (function () {

  var sharedId = 0;

  var ctor = function () {
  
    var id = this.id();

    this.id = function () {
      return (id);
    };
  };

  ctor.prototype.id = function () {

    return (sharedId++);
  };

  return (ctor);

})();

although another option might be to defer making the id for the instance until it is first asked for but your object instances then get numbered differently;

var MyType = (function () {

  var sharedId = 0;

  var ctor = function () {

  };

  ctor.prototype.id = function () {

    var id = sharedId++;

    this.id = function () {
      return (id);
    };

    return (id);
  };

  return (ctor);

})();

and I guess that’s the first one that really is a self-defining function.

Reference: Stefanov, “JavaScript Patterns” Page 68

OMG #28 – This or That?

This is absolutely a re-statement of OMG #24. Why am I repeating myself? Because I keep banging my head against this one and it’s probably one of the things that would really trip me up again and again. I’d go so far as to say that I really wish that JavaScript had no use of the word this whatsoever because it’s just confusing (to me, anyway Smile).

Where I’m being bitten by this the most is in event handlers. I do something that seems intuitive or, almost, second nature to me;

var MyType = function () {
};

MyType.prototype.x = 0;
MyType.prototype.y = 0;
MyType.prototype.handler = function()
{
  var sum = this.x + this.y; // Woops!
};

document.addEventListener("DOMContentLoaded", function () {

  var button = document.getElementById("button");

  var myInstance = new MyType();

  button.addEventListener("click", myInstance.handler);

});

and it’s once again my expectation that in my function called handler there will be a this pointer to make use of whereas when that function is called from the event handler, the this pointer can’t possibly be passed because it wasn’t part of what was given to the event handler in the first place.

It’s not “so hard” to fix this kind of problem with something like;


var MyType = function () {
};

MyType.prototype.x = 0;
MyType.prototype.y = 0;
MyType.prototype.handler = function()
{
  var sum = this.x + this.y; // Now ok 🙂
};

document.addEventListener("DOMContentLoaded", function () {

  var button = document.getElementById("button");

  var myInstance = new MyType();

  button.addEventListener("click", function () {
    myInstance.handler();
  });

});

but it’s catching me out again and again Smile

Reference: Stefanov, “JavaScript Patterns” Page 68

OMG #29 – Events

I don’t think this one is really JavaScript’s “fault” as such as I don’t think that the language has fully fledged support for events and so you’re left to model events as a list of function pointers.

Looking at something simple like a button, you end up with an onclick event which you can either handle by assigning a function to that property on the button or by using addEventListener to add your handler to the event.

document.addEventListener("DOMContentLoaded", function () {

  var b = document.getElementById("butt");

  b.onclick = function () {
    var x = 10;
  }

});

and in that snippet I used addEventListener to sync up to the event on the document whereas I used onclick =  to sync up to the event on the Button.

Now, I thought I had this pretty well understood in that it’s fairly easy to understand that addEventListener is going to let the event have multiple listeners whereas doing the onclick = assignment is going to presumably overwrite any event listener that was already stored in the onclick property.

I thought I had it all sorted until I came to work with a “type” that I didn’t understand. I’d written code something like;

function SomeFunction() {
 
  var instance = new SomeoneElsesType();

  instance.onchanged = function () {
  };

}

and this “SomeFunction” code runs many times in my application and I was quite happy with the idea that I was the only listener that would subscribe to this onchanged event and so it didn’t matter that I wasn’t using addEventListener.

That proved to be true until I figured out that the SomeoneElsesType turned out to implement a form of singleton pattern which meant that the onchanged property was effectively a singleton which meant that my overwriting of the event rather than using addEventListener actually did matter and I couldn’t get away with it.

What did I learn? Always use addEventListener even when you think that you don’t need it as otherwise you can get bitten by someone else’s implementation choices.

OMG #30 – “JavaScript, it’s just like everywhere!” Winking smile

Number 30 will be the last of these “OMG” posts. They were just a bit of fun while I took some initial steps although I’d say that I’ve encountered most if not all of the 30 (ok, 29) many, many times over the last month or so which has seen me doing more work with JavaScript than I’ve ever done before.

Of course, I never needed to write any of these things down. JavaScript information and snippets and techniques and tools and libraries are all over the internet. There are examples at http://wtfjs.com/ and http://bonsaiden.github.com/JavaScript-Garden/ and no doubt lots of other places so these were just a place for jotting down some of my own experiences but, for now, I’m done.

You can find the rest of these “JavaScript OMG!!” entries here

JavaScript OMG #21 to #25

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 #21 – Everything’s a Function

There’s a piece of code in Crockford’s book that I had to read about 5 times. He (very tersely) defines a new method on all functions called method (this is his code below);

Function.protoype.method = function(name, func) 
  {
    this.prototype[name] = func;
    return(this);
  };

because it’s altering the prototype for Function I read that as adding a method (called method) to every Function object and that new method knows how to add another method of a given name and implementation to the prototype. Wow.

It’s used something like below and I think it’s fairly well known/understood/etc;

String.method(
  'lengthSquared', 
  function() 
  { 
    return(this.length * this.length); 
  }
);

My function here makes a new lengthSquared function available on on any string.

The brilliance of this is quite something but for the first few readings of it, I kept saying to myself;

“How can Function.protoype be used to add a method to a String when String is not a function. It’s a class or a type but not a function!!

because I wasn’t thinking like JavaScript – of course String isn’t a class or a type, it’s a function.

In fact – I think I’ll call this “Mike’s First Law of JavaScript – It’s a Function, Stupid” Smile

Reference: Crockford, “JavaScript, The Good Parts”, Page 33.

OMG #22 – array.sort() won’t sort numbers “correctly”

Not if you leave it to do its own thing, anyway.

Reference: Crockford, “JavaScript, The Good Parts”, Page 80.

OMG #23 – parseInt() needs help

I hadn’t appreciated that this would happen and that, by default, the “09” would be interpreted as octal;

var myString = "09";
var myOctalInteger = this.parseInt(myString);
var myDecimalInteger = this.parseInt(myString,10);
console.log(myOctalInteger);
console.log(myDecimalInteger);

Reference: Stefanov, “JavaScript Patterns”, Page 23.

OMG #24 – Callbacks and Scope

This one is going to be a very hard one to get used to. Let’s say I was writing some C# code that made use of simple, instance method passed as a callback;

 class MyType
  {
    string text = "some text";
    public void Print() { Console.WriteLine(this.text); }
  }
  class Program
  {
    static void Main(string[] args)
    {
      MyType m = new MyType();
      Wrapper(m.Print);
    }
    static void Wrapper(Action callback)
    {
      callback();
    }
  }

Pretty simple – the fact that the method Print is an instance method isn’t lost at the point where the function reference is passed to the Wrapper function which calls back to it and so this code prints “some text”.

I need to try and remember that JavaScript is very different;

var myObj = {
  text : "some string",
  print : function() { console.log(this.text); }
};

var wrapper = function(callback)
    {
      callback();
    };

// undefined. myObj.print is a function, not some
// combination of a function and an object reference
// to invoke it on.
wrapper(myObj.print);

and I guess to achieve a similar thing I’d need to make sure it was called on the right object with something like;

var myObj = {
  text : "some string",
  print : function() { console.log(this.text); }
};

var wrapper = function(instance, callback)
    {
      callback.call(instance);
    };

// logs "some string"
wrapper(myObj, myObj.print);

Reference: Stefanov, “JavaScript Patterns”, Page 64.

OMG #25 – Function Literals Create Functions

I’m not sure that I have the name of this “OMG!” correct but what I wanted to convey (partly, maybe mostly to myself) is to take care over where methods are created. Here’s a function that creates and returns an array of 2 functions;

var functionArray = 
    (function()
     {
       var i = 0;
       var arr = [];
       
       for (i = 0; i < 2; i++)
       {
         arr[i] = function() { return(1); }
     }
     return(arr);
    })();

console.log(functionArray[0] === functionArray[1]);

Now I would not be at all surprised if the interpreter were smart enough to see those 2 functions, spot them as identical and return the same function. However, as far as I know it doesn’t so creating functions like this in a loop would be a bad idea.

Reference: Crockford, “JavaScript, The Good Parts” Page 39

I’m not yet 100% sure how this does or doesn’t tie up with prototypes. Below, I’m trying to have an accessor method getName() which hides the instance state that it relies on. I do this by relying on the closure to capture the value of the parameter name to the constructor. Because of this, it feels like I’d have to have a separate function constructed for each instance of Turtle in order to capture the parameter value. I’m still pondering on that one so feel free to comment Smile

var Turtle = function(name)
    {
      this.getName = function()
        {
          return(name);
        };
    };

var t1 = new Turtle("Eric");
var t2 = new Turtle("Ernie");

console.log(t1.getName());
console.log(t2.getName());

// These are not the same method. I'm wasting methods!
console.log(t1.getName === t2.getName);

Reference: Stefanov, “JavaScript Patterns” Page 101

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

JavaScript OMG!: #16 to #20

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#16 – Function Arguments

I think it was C# 4.0 that finally got around to the notion of optional and named arguments to a function whereas JavaScript is way ahead with the sort of zany stuff that you get to do when writing a function.

"use strict";

function f (a, b, c)
{
  console.log("Arg a present " + (a !== undefined));
  console.log("Arg b present " + (b !== undefined));
  console.log("Arg c present " + (c !== undefined));
  
  if (arguments.length > 3)
  {
    for (var i = 3; i < arguments.length; i++)
    {
      console.log("Extra argument " + arguments[i]);
    }
  }
}

// too few args leaves b,c undefined.
f(10);

// too many args is not a problem.
f(10,20,30,40,50);

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 171-173.

OMG #17 – Nested Functions

I really like the very natural way that I can define functions inside of functions in JavaScript and, optionally, form closures over the local variable state.

"use strict";

function moduloCounter(modulo)
{
  // only way to get back to this variable will be via functions
  // I return keeping it out of anything publicly assessible.
  var counter = 0;
  
  return(
    {
      inc : function()
      {
        counter++;
        if (!(counter - modulo))
        {
          counter = 0;
        }
        return(counter);
      },
      dec : function() 
      {
        counter--;
        if (counter < 0)
        {
          counter = (modulo - 1);          
        }
        return(counter);
      },
      valueOf : function()
      {
        return(counter);
      }
    }
    );
}

var module8 = moduloCounter(8);

for (var i = 0; i < 16; i++){
  console.log(module8.inc());
}

for (var i = 0; i < 16; i++)
{
  console.log(module8.dec());
}

That’s pretty clever stuff although it takes a bit of getting used to and it feels that this sort of technique has a lot of power to it.

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 166.

OMG #18 – Arrays versus Lists

Arrays seem fairly easy to get to grips with in JavaScript but there’s a few differences to what you’d see in .NET that leads to the JavaScript array feeling more like .NET’s ArrayList in many ways. One is around the idea that I can just add things to an array whenever and wherever I feel like it;

var myArray = [1,2,3];

myArray.push(4); 

console.log(myArray); // 1,2,3,4

var last = myArray.pop();

console.log(myArray); // 1,2,3

myArray.unshift(0);

console.log(myArray); // 0,1,2,3

var first = myArray.shift();

console.log(myArray); // 1,2,3

myArray[99] = 'mixed content';
console.log(myArray.length); // 100

console.log(myArray[98]); // undefined
console.log(98 in myArray); // false

myArray[98] = undefined; 
console.log(myArray[98]); // undefined
console.log(98 in myArray); // true

// arrays are still objects of coure
myArray.whatever = "anything I like";
console.log(myArray.whatever);

and there’s the difference between an array “element” being in the array and undefined versus it simply not being in the array which I tried to highlight. There’s also a lack of multi-dimensional arrays but that’s not so hard to solve with arrays of arrays.

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 151,152.

OMG #19 – Function Invocation Context & Strict Mode

I find this one a bit tricky (to say the least). If I’m writing a plain old, vanilla function then the this pointer is set to the global object? Ouch!

function foo(){
  this.x = 10;
}

foo();

console.log(this.x); // 10, scary 🙂

It’s “nice” to see that ES5 strict mode comes along and try to tidy this up but I don’t suppose that offers much consolation outside of a strict environment.

"use strict";

function foo(){
  this.x = 10; // TypeError: cool!
}

foo();

console.log(this.x); 

I could see hours going down the drain to bugs introduced by those kinds of problems.

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 167.

OMG #20 – Nested Functions & Invocation Context

This feels like another “gotchya” to me and combines with OMG #19 above. If I have a nested function inside a method;

this.x = 101;

var myObject = {
  x: 1,
  y: 1,
  myFunction: function()
  {
    var myNestedFunction = function()
        {
          return(this.x);
        };
    return(myNestedFunction());
  }
};

console.log(myObject.myFunction());

then even it picks up the global object for its invocation context unless I’m in strict mode when it throws an error. What I should be doing is picking up the this pointer myself such that the nested function captures it but that’d be easy to forget Smile

"use strict";

this.x = 101;

var myObject = {
  x: 1,
  y: 1,
  myFunction: function()
  {
    var self = this;
    var myNestedFunction = function()
        {
          return(self.x);
        };
    return(myNestedFunction());
  }
};

console.log(myObject.myFunction());

Reference: Flanagan, “JavaScript The Definitive Guide”, Page 169.

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