Sergio and the sigil

JavaScript: Avoid the Evil eval

Posted by Sergio on 2009-03-31
This post is part of a series called JavaScript Demystified.

I'm pretty sure by now you have heard at least once that eval is evil. Some nuggets from Eric Lippert's post:

if you are considering using eval then there is probably a better way
People, eval starts a compiler.

I'm also pretty sure I don't need to tell you that anytime you have an explicit eval() in your code, there's a good chance it's there because you're not taking JavaScript seriously yet.

//mandatory square brackets notation example
//------------------------------------------
var myObject = new MyObject();
var prop1 = eval( 'myObject.' + somePropertyName ); // BAD!
var prop2 = myObject[ somePropertyName ]; // Better

That's not the end of all eval()

At this point some people might be feeling relieved: "Phew! That was easier than it sounded. Getting rid of eval is a piece of cake." Well, I'm not going to say it's significantly harder than that, but we're not done prunning eval() from our code just yet.

You see, eval() is like that coward opponent that sneaks in the dark to attack you from behind. Let's find some of eval's favorite hiding places.

There's a time when you need a timer

Two very popular JavaScript functions used to create timers are setTimeout() and setInterval(). Here's how you still find code being written to use them.

function doSomething(someValue){
	//...
}

setTimeout("doSomething('3 seconds elapsed. Time is up.');", 3000);

As it turns out, this is just another occurrence of eval() revealing how incompetent we can still be in this programming language. Here's a better way to write that code.

setTimeout( function(){ 
                doSomething('3 seconds elapsed. Time is up.');
            }, 
            3000);

Thank God I didn't know functions had constructors

The other secret place that eval() likes to hang out is in the Function constructor. Fortunately this isn't exactly a popular way of creating functions. I'll say it: I didn't even know about this constructor until less than a couple of years ago.

So, in case you don't know what I'm talking about here, I'll show you how to use the function constructor just to imemdiately tell you to not do it.

var sum = new Function('op1', 'op2', 'return op1 + op2;');
var result = sum(10, 20); // ==> 30

The above code is roughly equivalent to the explicit eval() usage below.

eval("var sum = function (op1, op2) { return op1 + op2; }");
var result = sum(10, 20); // ==> 30

We don't come up with the need to use the function constructor often, but I'll admit that when we do, it's usually hard to replace it with another way that doesn't use eval().

Minor update: I was doing some snooping around with Firebug and Reflector and found that WebUIValidation.js (embedded in System.Web.dll) does use eval() in some ways that I just pointed out to be unnecessary. If that is of any comfort to anyone that has done the same in the past, there you have probably the largest deployment of misused eval() I know of.

JavaScript, inner functions and private members

Posted by Sergio on 2009-02-24
This post is part of a series called JavaScript Demystified.

In our last installment in this short JavaScript series we took a look at closures. In some of the examples, we saw functions being declared (and returned) inside other functions. The capability of declaring a function inside another one is not common to all languages — C# only added this ability in version 2.0, via anonymous delegates.

Here's an example of inner functions in use.

function printPriceLong(name, price, quantity, currency) {
	var formatCurrency = function(value) {
		return value + ' ' + currency;
	};
	return 'Item: ' + name + '\n' +
		'Unit price: ' + formatCurrency(price) + '\n' +
		'Quantity: ' + quantity + '\n' +
		'TOTAL: ' + formatCurrency(price * quantity);
}

alert( printPriceLong('100g Toblerone bar', 2.09, 3, 'USD') );
/* =>
Item: 100g Toblerone bar
Unit price: 2.09 USD
Quantity: 3
TOTAL: 6.27 USD
*/

If we try to call formatCurrency from anywhere outside of printPriceLong we are going to cause an error because formatCurrency is scoped only inside its parent function.

In this example we can also see closures in action once again. The currency value is referenced inside formatCurrency but it's declared in it's parent. It's a short-lived closure, mind you, because we are not returning that inner function. It's discarded as soon as the parent function exits.

Who said JavaScript objects can't have private members?

Developers sometimes get upset when they realize that anyone has read and write access to the fields and methods of their JavaScript objects. Most of us are used to work with languages that allow us to declare some of our object's members out of reach for the calling code. We say that these members are private and we don't want anyone changing or even seeing them.

Well, this is not exactly true. If you must have private members in your JavaScript objects, you can. Inner functions and closures will come to our rescue.

Let's build on our previous example. Let's create an OrderItem object that will hold those values (name, price, etc.) Let's assume we do not want anyone changing the object's price without changing the currency at the same time (to ensure some level of consistency.) We could code our object like this:

function OrderItem(productName, price, quantity, currency) {
	//regular properties
	this.name = productName;
	this.quantity = quantity;

	//read accessors
	this.getCurrency = function(){ return currency; };	
	this.getPrice = function(){ return price; };
	//write accessor
	this.setPrice = function(newPrice, newCurrency){
		if(typeof newPrice !== 'number' || newPrice < 0){
			throw { message:'invalid price' };
		}
		if(typeof newCurrency !== 'string'){
			throw { message:'invalid currency' };
		}
		price = newPrice;
		currency = newCurrency;
	};

	//a private function
	var formatCurrency = function(value) {
		return value + ' ' + currency;
	};
	
	//methods that need private members
	this.getUnitPriceString = function(){
		return formatCurrency(price);
	};
	this.getTotalPriceString = function(){
		return formatCurrency(price * quantity);
	};
}

OrderItem.prototype = {
	//overriding the string representation of the object
	toString: function(){
		return  'Item: ' + this.name + '\n' +
			'Unit price: ' + this.getUnitPriceString() + '\n' +
			'Quantity: ' + this.quantity + '\n' +
			'TOTAL: ' + this.getTotalPriceString();	
	}
};

That seems a bit long, but hopefully we can understand what's going on here. We are letting name and quantity be regular read/write properties but we never defined properties for price or currency. We made those two values accessible via the getPrice and getCurrency methods, respectively.

The trick here is that both getPrice and getCurrency are defined inside our constructor function so they have access to the local variables price and currency. They have access to these variables even after the constructor returns (thank you closures.)

The same can be said for the setPrice method. We will use this method when we need to change the object's price. It will force us to also provide a currency.

I'll leave the explanation of the methods getUnitPriceString and getTotalPriceString as an exercise for you.

Let's instantiate one of these objects and see it in action.

var item = new OrderItem('100g Toblerone bar', 2.09, 3, 'USD');
//public methods:
alert( item.getUnitPriceString() );
// => '2.09 USD'
alert( item.getTotalPriceString() );
// => '6.27 USD'
alert(item); //this will use the toString() method
/* =>
Item: 100g Toblerone bar
Unit price: 2.09 USD
Quantity: 3
TOTAL: 6.27 USD
*/

//changing private fields
item.setPrice(1.11, 'EUR');
alert( item );
/* =>
Item: 100g Toblerone bar
Unit price: 1.11 EUR   <-- it worked!
Quantity: 3
TOTAL: 3.33 EUR
*/

//proving that price is not a field
item.price = '5.00';
alert( item.getUnitPriceString() );
// => '1.11 EUR' <-- Gotcha, smart pants!

item.setPrice(2);
//ERROR: message = 'invalid currency'
alert( item.formatCurrency(1.23) );
//ERROR: item.formatCurrency is not a function

And what am I supposed to do with this information?

I have yet to find the need to use private members in my JavaScript objects. Maybe that's because I am not shipping any JavaScript library with complex enough objects.

I think it's nice to know that you can create those off-limits values in your object. Hopefully when the need for such thing arises, we won't just say Oh, no! Can't do that!.

What about you? Have you found a use for private members in your JavaScript code? How did you get around or implemented it?

JavaScript, time to grok closures

Posted by Sergio on 2009-02-23
This post is part of a series called JavaScript Demystified.

When I wrote about functions in JavaScript I mentioned that functions are more than just a block of code:

Function is a standard data type in JavaScript, an object indeed; you can pass them around and copy them.

Let's take a look at this small sample of a function that creates and returns another function. The returned function accepts one string argument and returns another string repeating the argument a number of times.

function makeRepeater(times){
	return function(text){
		var message = '';
		for (var i=0; i < times; i++) {
			message += text + ' ';
		}
		return message;
	};
}

Let's now write some code that uses that function.

var threeTimes = makeRepeater(3);
var fourTimes = makeRepeater(4);
alert( threeTimes('hi') );
// => 'hi hi hi '
alert( fourTimes('hi') );
// => 'hi hi hi hi '

Nothing spectacular, right? But look closely. The function returned by makeRepeater contains a reference to times, which is a local variable of makeRepeater. When we call threeTimes or fourTimes the makeRepeater call has already returned and times should be out of scope. Or should it?

Extra life for your local scope

You may try to argue and say that the times inside threeTimes is not a reference to the times from makeRepeater, but just a copy of that value. Well, sadly I'll have to prove you wrong. Let's modify our code just a little.

var times;
function makeRepeater(){
	return function(text){
		var message = '';
		for (var i=0; i < times; i++) {
			message += text + ' ';
		}
		return message;
	};
}

times = 3;
var threeTimes = makeRepeater();
times = 4;
var fourTimes = makeRepeater();
alert( threeTimes('hi') );
// => 'hi hi hi hi '  ---> What?!?!
alert( fourTimes('hi') );
// => 'hi hi hi hi '

If it's not clear yet, let me write it down for you. The returned function really keeps a reference to any outside values it will need when invoked. In our original example, it kept a reference to the times local variable at the time it was produced. If we had created other local variables inside makeRepeater they would also become available inside the returned function. In other words, all the scope created during the call to makeRepeater will be preserved for the returned function. This happens when the returned (or inner) function has a reference to anything defined in the parent (or outer) function, i.e. the parent local scope. When this happens, we say that a closure has been created.

Closures can be tricky

It's important to understand the mechanics of closures to avoid subtle bugs in our code. Look at this piece of code, adapted from a real bug I had to fix.

<input type="button" value="Button 1" id="btn1">
<input type="button" value="Button 2" id="btn2">
<input type="button" value="Button 3" id="btn3">

<script type="text/javascript">
	function createEventHandlers(){
		var btn;
		for(var i=1; i <= 3; i++){
			btn = document.getElementById('btn' + i);
			btn.onclick = function(){
				alert('Clicked button #' + i);
			}
		}
	}
	createEventHandlers();
</script>

If you put this code in a page and click the three buttons you will see that all of them will show the message "Clicked button #4". Armed with our understanding of closures we can immediately understand that this bug is being caused by that reference to i used inside the event handler. We can fix that.

function createEventHandlers(){
	var btn;
	for(var i=1; i <= 3; i++){
		btn = document.getElementById('btn' + i);
		btn.onclick = createOneHandler(i);
	}
}

function createOneHandler(number){
	return function() {
		alert('Clicked button #' + number);
	}
}

The above code works because we are not creating functions inside the for loop, hence not producing closures on the same local scope. There is a different set of closures being produced by createOneHandler, but those are not pointing to the same parent scope. Each of these three new closures contain a different scope, created by each call to createOneHandler

Closing thoughts

Closures, of course, are not an exclusive feature of JavaScript. It's a very important trait of functional languages. Even in C#, when we use lambdas, closures are created — many times without us noticing.

The key to properly using closures in our code is to pay attention to locally scoped values from the outer function being used in the body of the inner function. Most of the times this will work as intended by the developer but, when it doesn't, stop and check if more than one closure is sharing the same local scope or if these local values are changing between the inner function creation and its invocation.

JavaScript, 5 ways to call a function

Posted by Sergio on 2009-02-09
This post is part of a series called JavaScript Demystified.

Time after time I find JavaScript code that has bugs caused by lack of proper understanding of how functions work in JavaScript (a lot of that code has been written by me, by the way.) JavaScript has functional programming characteristics, and that can get in our way until we decide to face and learn it.

For starters, let's examine five ways to invoke a function. On the surface we might be tempted to think that functions work exactly like C#, but we will see that there are important differences and ignoring them will undoubtedly result in hard to track bugs.

Let's first create a simple function that we will be using through the rest of this post. This function will just return an array with the current value of this and the two supplied arguments.

<script type="text/javascript">
function makeArray(arg1, arg2){
	return [ this, arg1, arg2 ];
}
</script>

Most common way, unfortunately, global function calls

When we are learning JavaScript we learn how to define functions using the syntax used in the example above. We learn that it's also very easy to call that function — all we need to do is:

makeArray('one', 'two');
// => [ window, 'one', 'two' ]

Wait a minute. What's that window object doing there? Why is it the value of this? If you haven't stopped to think about it, please stay with me here.

In JavaScript, and I'm not talking specifically about the browser here, there's a default/global object. It's as if every code that we write which seems to be just "loose" inside your script (i.e. outside of any object declaration) is actually being written in the context of that global object. In our case, that makeArray function isn't just a loose "global" function, it's a method of the global object. Bringing ourselves back to the browser, the global object is mapped to the window object in this environment. Let's prove that.

alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// => function

What all this means is that calling makeArray like we did before is the same as calling as follows.

window.makeArray('one', 'two');
// => [ window, 'one', 'two' ]

I say it's unfortunate that this is the most common way because it leads us to declare our functions globally by default. And we all know that global members are not exactly the best practice in software programming. This is especially true in JavaScript. Avoid globals in JavaScript, you won't regret it.

JavaScript function invocation rule #1 In a function called directly without an explicit owner object, like myFunction(), causes the value of this to be the default object (window in the browser).

Method call

Let's now create a small object and use the makeArray function as one of its methods. We will declare the object using the literal notation. Let's also call this method.

//creating the object
var arrayMaker = {
	someProperty: 'some value here',
	make: makeArray
};

//invoke the make() method
arrayMaker.make('one', 'two');
// => [ arrayMaker, 'one', 'two' ]
// alternative syntax, using square brackets
arrayMaker['make']('one', 'two');
// => [ arrayMaker, 'one', 'two' ]

See the difference here? The value of this became the object itself. You may be wondering why isn't it still window since that's how the original function had been defined. Well, that's just the way functions are passed around in JavaScript. Function is a standard data type in JavaScript, an object indeed; you can pass them around and copy them. It's as if the entire function with argument list and body was copied and assigned to make in arrayMaker. It's just like defining arrayMaker like this:

var arrayMaker = {
	someProperty: 'some value here',
	make: function (arg1, arg2) {
		return [ this, arg1, arg2 ];
	}
};
JavaScript function invocation rule #2 In a function called using the method invocation syntax, like obj.myFunction() or obj['myFunction'](), causes the value of this to be obj.

This is a major source of bugs in event handling code. Look at these examples.

<input type="button" value="Button 1" id="btn1"  />
<input type="button" value="Button 2" id="btn2"  />
<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>

<script type="text/javascript">
function buttonClicked(){
	var text = (this === window) ? 'window' : this.id;
	alert( text );
}
var button1 = document.getElementById('btn1');
var button2 = document.getElementById('btn2');

button1.onclick = buttonClicked;
button2.onclick = function(){   buttonClicked();   };
</script>

Clicking the first button will display "btn1" because it's a method invocation and this will be assigned the owner object (the button input element.) Clicking the second button will display "window" because buttonClicked is being called directly (i.e. not like obj.buttonClicked().) This is the same thing that happens when we assign the event handler directly in the element's tag, as we have done for the third button. Clicking the third button does the same of the second button.

That's another advantage of using a library like jQuery. When defining event handlers in jQuery, the library will take care of overriding the value of this and make sure it contains a reference to the element that was the source of the event.

//using jQuery
$('#btn1').click( function() {
	alert( this.id ); // jQuery ensures 'this' will be the button
});

How does jQuery override the value of this? Keep reading.

Two more: apply() and call()

The more you leverage functions in JavaScript, the more you find yourself passing functions around and needing to invoke them in different contexts. Just like jQuery does in the event handler functions, you'll often need to override the value of this. Remember I told you functions are objects in JavaScript? Functions have predefined methods, two of them are apply() and call(). We can use them to do precisely that kind of overriding.

var gasGuzzler = { year: 2008, model: 'Dodge Bailout' };
makeArray.apply( gasGuzzler, [ 'one', 'two' ] );
// => [ gasGuzzler, 'one' , 'two' ]
makeArray.call( gasGuzzler,  'one', 'two' );
// => [ gasGuzzler, 'one' , 'two' ]

The two methods are similar. The first parameter will override this. They differ on the subsequent arguments. Function.apply() takes an array of values that will be passed as arguments to the function and Function.call() takes the same arguments separately. In practice I believe you'll find that apply() is more convenient in most cases.

JavaScript function invocation rule #3 If we want to override the value of this without copying the function to another object, we can use myFunction.apply( obj ) or myFunction.call( obj ).

Constructors

I won't delve into the details of defining types in JavaScript but at minimum we should be aware that there aren't classes in JavaScript and that any custom type needs a constructor function. It's also a good idea to define the methods of your type using the prototype object, which is a property of the constructor function. Let's create a small type.

//declaring the constructor
function ArrayMaker(arg1, arg2) {
	this.someProperty = 'whatever';
	this.theArray = [ this, arg1, arg2 ];
}
// declaring instance methods
ArrayMaker.prototype = {
	someMethod: function () {
		alert( 'someMethod called');
	},
	getArray: function () {
		return this.theArray;
	}
};

var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );

am.getArray();
// => [ am, 'one' , 'two' ]

What's very important to note here is the presence of the new operator before the function call. Without that your function will just be called like a global function and those properties that we are creating would be created on the global object (window.) And you don't want to do that. Another issue is that, because you typically don't have an explicit return value in your constructor function, you'll end up assigning undefined to some variable if you forget to use new. For these reasons it's a good convention to name your constructor functions starting with an upper case character. This should serve as a reminder to put the new operator before the call.

With that taken care of, the code inside the constructor is very similar to any constructor you probably have written in other languages. The value of this will be the new object that you are trying to initialize.

JavaScript function invocation rule #4 When used as a constructor, like new MyFunction(), the value of this will be a brand new object provided by the JavaScript runtime. If we don't explictly return anything from that function, this will be considered its return value.

It's a wrap

I hope understanding the differences between the invocation styles help you keeping bugs out of your JavaScript code. Some of these bugs can be very tricky do identify and making sure you always know what the value of this will be is a good start to avoiding them in the first place.

Language Envy - String Interpolation

Posted by Sergio on 2009-01-17
Language Envy: This post is part of a series where I wish C# had a particular feature I came to like when working with other programming languages.

Every time I have to produce a string in C# the little groaning chimp that lives inside my head pulls his hair out. It's about time we had a better way of doing this.

We all use string.Format to make these string concatenations more readable, but it's still too easy to get the order wrong or miss one of the argument values and get an exception. JetBrain's Resharper can be helpful here, giving hints when you have too many or too few arguments in a call to string.Format.

So what am I whining about?

When you need to create a string that mixes literals with variables in PHP (or Ruby, or Boo, or Perl, etc) it's so much easier to type, read and maintain than in C#:

<?php
	$price = 12.34;
	$product = "DVD Media";
	echo "$product costs $price";
	//ouputs: DVD Media costs 12.34
?>

Although this would be enough to get a lot done, the interpolation syntax can help with more complicated expressions beyond simple variables:

<?php
	$order = $user->getLastOrder();
	echo "The first item in the order was {$order->item[0]}.";
	//ouputs: The first item in the order was DVD Media.
?>

One interesting thing to note is that this is a syntax for combining expression values and literals. The interpolation isn't evaluated in strings that already exist and are passed in (like some user input.) In other words, the interpolation happens at parsing time, where the string is declared. The parser will not look into an existing string and replace tokens that look like variables — at least not without you explicitly asking it to do so.

In PHP the interpolation goes a little further. Just for the sake of curiosity, check this out.

<?php
	$var1 = 1000;
	$name = 'var1';
	//recursive interpolation:
	echo "The value of the variable named $name is {${$name}}";
	//outputs: This is the value of the var named var1 is 1000 
?>

Wouldn't it be nice to have such syntax in C#? The string would probably need to be taken care of at compile time, so a statement like this:

//DOESN'T WORK YET. JUST A DAYDREAM
var text = "The price of a ${product.Name} is ${product.Price}.";

At compile time would be treated as if it had been written as follows.

var text = "The price of a " + product.Name + 
           " is " + product.Price + ".";
// OR ...
var text = string.Concat("The price of a ", product.Name, 
           " is ", product.Price, ".");

Done like the example above this would be a backwards compatibility problem. I'm sure it's possible to put some symbol before the opening double quote to make this compatible.