Javacript: Binding, call and apply methods

Continuing my interest in Javascript this would be second in the series of Posts revisiting the basics of Javascript.

One of the many things that I have been ignorant about when it comes to Javascript is the existence of bindings. Like Ruby ( and other languages) Javascript uses bindings to allow functions to be called with reference to a specific object.

I like to think of this as something similar to instance_eval in Ruby or the binding method.

Instance_eval evaluates an object in the context of an object its called with so lets take a simple example in Ruby


class Cat
def speak
 "miaow"
end
end

class Dog
def speak
"Bark"
end
end

d = Dog.new
=> #
>> c = Cat.new
=> #
>> c.instance_eval{ speak }
=> "miaow"

All this describes is that the speak method is invoked with reference to the instance c (Cat Object)

Similarly the binding method

class Person
  def bind
   @var = "Person Object"
  binding
 end
end

>> p= Person.new
=> #
>> b = p.bind
=> #
>> eval("@var", b)
=> "Person Object"

“binding” which is a kernel method provides us with a binding or snapshot of the context at a particular place in the code where it retains the execution context such as the variable values (@var in this example) which can be used at a later point. With eval we evaluate the value of the @var variable with respect to the binding generated earlier.

Similary Javascript provides us with the apply and call methods. Based on Christophe Porteneuve’s example on the listapart blog here is a simple example to illustrate the use of apply
and call methods


function Song(band, album, song){
	this.band = band;
	this.album = album;
	this.song = song;
	
	this.info = function(other){
		console.log(this);
			alert( 'Did you know '  + other.band + " covered " + this.band + "\'s " + this.song ); 
		}
		
	
	
}



var korn = new Song('Korn','Another Brick in the Wall', 'Another Brick in the Wall' );
var pink = new Song('Pink Floyd', 'The Wall', 'Another Brick in the Wall');

pink.info(korn);

In this case we see a message that says “Did you know Korn covered Pink Floyd’s Another Brick in the Wall”. So thats cool.

The problem occurs when the reference is lost (binding loss: when you assign a method to a variable or pass it as an argument). So lets append this to our earlier example

function display_info(fn, args){
	
		fn(args);
	
}

display_info(pink.info, korn);

Now we see “Did you know Korn covered undefined’s undefined”. The logger statement in the info method will show you that “this” actually is pointing to the window object and not Object of type Song. This is because the minute the binding it lost “this” starts referring to the default binding that is the window object.

So we solve the problem using call or apply. Add this to the bottom of the display_info method

	fn.apply(pink, [korn]);
	fn.call(pink, korn);

Now we see it works again. All we do here with the call and apply method is specify explicitly that we would be invoking the fn i.e. pink.info with reference to the pink object with the korn object as an argument.

So whats the difference between call an apply then? Nothing except that call expects individual arguments to be passed while apply accepts an array

        fn.apply(BindingObject, ArrayArgument);
	fn.call(BindingObject, Argument1, Argument2...);

The inferences drawn in this post have been learned from Christophe Porteneuve’s post titled Getting Out of Binding Situations in JavaScript from the ListApart Blog. Its an awesome post and definitely a must read if your interested in Javascript.

Javascript: Awesomeness

I have been working with Javascript for over a year now and have been using it as language to manipulate the DOM. I had never taken Javascript seriously enough or thought of it to be a real language till a few months back when I had to start working with Orbited.

Recently I went back to understand the basics of Javascript and I decided to go through some of the things that I found were really awesome. Now most of this stuff may be lame for experienced programmers but I hope this helps someone who starting off.

Objects

I knew that Javascript had primitives and Object types. So going through a small example here

var s = "Mary had a little lamb";
alert(typeof s); // This would display 'string'

var ss = new String("Bazingaa");
alert(typeof ss); // This would display 'Object'

If you notice, without really having the need to define an object javascript still lets you call methods on primitives types. For example

 var s = "Soft Kitty";
alert(s.length); // 10

Javascript creates transient objects for all primitives types so that methods may be called upon them and destroys them when no longer needed. (How cool is that!).

So now the question is are strings passed by reference or by value, because all primitives types are passed by value and Objects passed by reference. The answer is, its hard to tell, but it doesn’t matter as strings are immutable so basically you cannot change the value stored in them and when you do you are in fact creating a new object.