Hi,
I would like to understand the working of the Function#methodize
method and yes, I have read this post:
http://groups.google.com/group/prototype-scriptaculous/browse_thread/thread/d9c5444eaa66bdaf/e8287ff38260f0a9?lnk=gst&q=methodize#e8287ff38260f0a9
, but it is still unclear for me.
I broke it down to something like a minimal case like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/
html;charset=iso-8859-1" />
<title>Test methodize</title>
<script language="javascript" type="text/
javascript">Function.prototype.update = function(array, args){
var array_length = array.length, length = args.length;
while(length --){
array[array_length + length] = args[length];
}
return array;
}
/*
Function.prototype.methodize = function(){
if(this._methodized){ return this._methodized;}
var __method = this;
return this._methodized = function(){
console.log(this);
var a = Function.prototype.update([], arguments);
return __method.apply(this, a);
};
}
*/
Function.prototype.methodize = function(){
if(this._methodized){ return this._methodized;}
var __method = this;
return this._methodized = function(){
console.log(this);
var a = Function.prototype.update([this], arguments);
return __method.apply(null, a);
};
}
window.addEventListener('load', function(){
var obj_a = {
value : 2,
name : 'obj_a'
};
var obj_b = {
value : 5,
name : 'obj_b'
}
var multiplier = function(times){
times = isNaN(times) ? 2 : times;
if(typeof this.value != 'undefined'){
return this.value * times;
}
else{ alert(this + ': does not have a value property!');}
};
obj_a.multiply = multiplier.methodize();
console.log(obj_a.multiply(3));
console.log(obj_a.multiply(10));
obj_b.multiply = multiplier.methodize();
console.log(obj_b.multiply(5));
}, false);
</script>
</head>
<body>
<div>Nothing to see here</div>
</body>
</html>
If you run the above code, you will get a series of alert messages as
you should, I think.
In my understanding calling methodize on any function for the first
time means creating a static _methodized method on that particular
function that did not exist so far, while any later call to it returns
a reference to this static method regardless where the call originates
from.
if(this._methodized){ return this._methodized;}
return this._methodized = function(){}
Through assignments any number of objects can have any named methods
to refer to _methodized, but the ‘this’ keyword inside it will always
points to that particular object from which I am calling it.
Following this argumentation replacing methodize with this makes the
above code work as expected:
Function.prototype.methodize = function(){
if(this._methodized){ return this._methodized;}
var __method = this;
return this._methodized = function(){
console.log(this);
var a = Function.prototype.update([], arguments);
return __method.apply(this, a);
};
}
Could someone explain why and how the null value for the thisArg
argument in the original version is used if it is always resolved to
the window object in a browser and how methodize works?