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
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
"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.