Binding, Getter/Setter and Mutable.js

admin
March 21, 2009 at 11:51 am

In this article I am going to write about setter & getter, Function.prototype.caller / arguments.callee.caller and an implementation of a Getter/Setter Class. I am also going to demystify (yeah sort of ;) ) the secret behind adobe flex’s data binding and openlaszlo’s constrain using the power of function.caller.

Javascript Getter & Setter

Recently there are some progress in implementation of setter and getter in javascript. After Mozilla introduced it to us long time ago, recently Safari also supports those methods. John Resig also wrote a cool article about setter and getter.

in the future we will be able to write:

1
2
3
4
a = {
set b(){},
get b(){}
}

this is great since it gives us more control over our variables. Defining setter and getter can be very effective avoiding the need of creating methods like setX(), setY() etc.

an example usage of setter would be:

1
2
3
a = {
set value(val){this._val = val < 0 ? 0 : val > 10 ? 10 : val;}
};

the code limit the number that can be assigned to a.value. If the number is smaller than 0@ @a.value will get the number 0@, if it is bigger than @10, it will be 10@. But you see the problem here, @this._val is not really private. you can still change a._val to bypass value setter.

Mutable.js

Today I did some experiment about how to implement this kind of features in today’s browsers. So I came up with Mutable.js

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = {
	value: new Mutable({
		value: 0,
		setter: function(value)
		{
			this.value = value < 0 ? 0 : value > 10 ? 10 : value;
		},
		getter: function()
		{
			return this.value;
		}
	})
};

So this code will allow you to access the property like this:

1
2
3
4
5
6
a.value(1);
// a.value = 1;
a.value(11);
// a.value = 10;
a.value()
// a.value = 10;

Ok, it is not new, and not as cool as real setter and getter. but there are some other cool features, so keep reading…

Big Brother is Watching You

I did also include eventlistener that will be triggered each time the value changes

1
2
3
4
5
6
7
8
9
10
var a = {
	value: new Mutable({value: 0})
};
 
a.value.watch(function(oldval, newval){alert(oldval+'changed to'+newval)});
 
a.value(2);
// a.value = 2
// alert: '0 changed to 2'
a.value.unwatch();

No Trespassing

I am also experimenting with Function.prototype.caller which allows you to check which function is accessing the function. It allows me to implement this feature.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = {
	value: new Mutable({value: 0})
};
 
var fn1 = function(){a.value(3);}
var fn2 = function(){a.value(4);}
var fn3 = function(){a.value(5);}
 
// protect a.value, so it can only be altered by fn1 & fn3
a.value.lock(fn1, fn3);
fn1()
// a.value = 3;
fn2()
// access denied. a.value = 3;
fn3()
// a.value = 5;

Flex’s Binding

After implementing this I got the Idea that function.caller can be used to create data binding just like in flex. If you have worked with flex or openlaszlo you will know how cool is it to be able just to bind a property by using {bracket}.

1
<textfield value="{mySlider.value + myWindow.width}">

Moving the slider will magically change the value of the textfield. how awesome! After some experiments I finally understand how it might be working. And I am going to tell you how to implement this in javascript!

Let start with analysing what is happening there. {mySlider.value + myWindow.width} is a string that will be converted to a function.

so let assume that it will be converted to this:

1
2
3
4
5
textfield = {
	set value(){
		this.$value = (mySlider.value + myWindow.width);
	}
}

so what happens here? if mySlider.value has a getter (myWindow.width too), the getter will be called. Using arguments.callee.caller we will be able to get the caller. and in this case it is the value setter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
textfield = {
	set value(){
		// this is to make easier to identify the function. arguments.callee is value setter function
		arguments.callee.bindable = true;
		this.$value = (mySlider.value + myWindow.width);
	}
}
mySlider = {
	constrains: [],
	get value(){
		var caller = arguments.callee.caller;
		// isBinded is to make sure that this function only once binded.
		if(caller && caller.bindable && !caller.isBinded)
		{
			constrains.push(caller);
			caller.isBinded = true;
		}
		return this.$value;
	}
	set value(x){
		this.$value = x;
		// this will alert textField to update its value;
		for(var i=0; i<this.constrains.length; i++)
			this.constrains[i]();
	}
}
 
// the same with myWindow

Now we can implement this to Mutable.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
textfield = {
	value: new Mutable({
		value: 0,
		setter: function(value)
		{
			this.value = value;
			alert('textfield-value:'+value);
		}
	})
};
 
mySlider = {value: new Mutable({value: 1})};
myWindow = {width: new Mutable({value:100})};
 
// now the magic
textfield.value.bind(function(){return mySlider.value() * 2 + myWindow.width();});
// alerts 'textfield-value:102'
 
mySlider.value(10);
// alerts 'textfield-value:120'
 
myWindow.width(200);
// alerts 'textfield-value:220'

Cool isn’t it? Unfortunately function.caller is not an ECMA standard, so not all javascript engine have that feature. Opera and Rhino don’t have it. But fortunately we have it in Firefox, IE and Safari, so may be it is big enough to be considered. What do you think?

update: Opera 10 will support this! Hooraay!

I hope this article is useful to you.

Mutable.js is available here.

4 Commentsrss »

  • dyu
    April 15, 2009
    3:49 pm

    Pretty cool. Some other frameworks do implement binding with their container-layout (works with all major browsers … e.g qooxdoo)

  • mee
    July 11, 2009
    9:04 pm

    DAHSYAT… ;)

  • March 30, 2017
    12:33 pm

    Get an expert academic writing assistance. We can write any paper on any subject within the tightest deadline.

  • May 11, 2017
    11:14 am

    Get Levitra Online Is Ephedraxin Like Vyvanse Does Keflex Work For Uti Viagra Purchase Without Perscription Amoxicillin Anti Propecia Effects Shedding viagra Cialis Generico De Venta Viagra Efectos Negativos Comprar Cialis En Mano Potenzmittel Viagra Cialis Und Kamagra 400mg Flagyl

Leave a comment