Long time ago, when I was learning C, and I understood the use of pointers, I started thinking if there was a way to pass the JavaScript variables by reference.
I had a lot of ideas, but they didn't worked as spected.
For example, for global variables in a browser, I could use:
function modifyVar(varName,newVal){
window[varName]=newVal;
}
var x=123;
alert(x);
modifyVar("x",321);
alert(x);
window[varName]=newVal;
}
var x=123;
alert(x);
modifyVar("x",321);
alert(x);
anyway, this was only valid for "Global" variables..
Then I thought about using caller.call (even do it is not exportable).
function modifyVar(varName,newVal){
modifyVar.caller.call(eval,varName+"="+newVal);
}
var x=123;
alert(x);
modifyVar("x",321);
alert(x);
modifyVar.caller.call(eval,varName+"="+newVal);
}
var x=123;
alert(x);
modifyVar("x",321);
alert(x);
anyway, this didn't work neither, there was an strange error named "Too much recursion".
Then, a lot of time after that, (actually.. yesterday), I realized that the Objects in javascript are passed as reference, so..
function modifyVar(obj,newVal){
obj.value=newVal;
}
var m={value: 1};
alert(x);
modifyVar("x",321);
alert(x);
obj.value=newVal;
}
var m={value: 1};
alert(x);
modifyVar("x",321);
alert(x);
and the attribute was modified successfully :).
Any way, this wasn't good enough, I wanted to be able to send a variable as a parameter in an instruction, and be able to modify it's content inside the function.
There's when I realize (after some testing), that I can set any variable as an object, and allow it to have any primitive value I want, for example:
var w=Object("some string");
will behave just like:
var w="some string";
and that:
var w=Object(123);
will behave just like:
var w=123;
and the same for regular expressions, functions, other objects, etc..
So by means of this, I was able to transform any variable into a "referenceable" variable.
Any way, for modifying this variable, I couldn't use any Assignment Operators, because they would destroy the Object.. I needed to modify it's contents from "inside", using it's Methods.
So I found three methods that returned the value of an object:
- toSource();
- toString();
- valueOf();
The last one is the most important one, it's value is the one that will be treated "officially", except for String and Source operations.. so by doing:
function modifyVar(obj,val){
obj.valueOf=obj.toSource=obj.toString=function(){return val}
}
obj.valueOf=obj.toSource=obj.toString=function(){return val}
}
we would actually be modifying the value of "obj".
any way, this wasn't just enough.. I wanted a way to reference variables as easy as in C or PHP.. so.. why not making a prototype function of object that allows me to modify the variable..
so I did this:
Object.prototype.$=function $(val){if(val)this.valueOf=this.toSource=this.toString=function(){return val};return val;};
so, variable.$("new val"); will modify the content of variable, "globally".
Here you can see the way this works:
// Object reference maker
Object.prototype.$=function $(val){if(val)this.valueOf=this.toSource=this.toString=function(){return val};return val;};
function value(variable){
// function to modify the variable through =
variable="new_value";
}
function reference(variable){
//function to modify the variable through reference
variable.$("new_value");
}
var w="standard"; // standard value
w=Object(w);// transform to object.
alert(w); // show that the value is still the same
// standard
value(w); // try to change it's content's via =
alert(w); // show if the content's have been modified
// standard
reference(w); // try to modify the content's via reference
alert(w); // show the new value
// new_value
Object.prototype.$=function $(val){if(val)this.valueOf=this.toSource=this.toString=function(){return val};return val;};
function value(variable){
// function to modify the variable through =
variable="new_value";
}
function reference(variable){
//function to modify the variable through reference
variable.$("new_value");
}
var w="standard"; // standard value
w=Object(w);// transform to object.
alert(w); // show that the value is still the same
// standard
value(w); // try to change it's content's via =
alert(w); // show if the content's have been modified
// standard
reference(w); // try to modify the content's via reference
alert(w); // show the new value
// new_value
Hope this is useful for anybody that requires to modify a "private" variable where it's not accessible.. here is an example of Object, and a way to modify its private variables (which shouldn't be possible due to the O.O.P. Paradigm)..
Object.prototype.$=function $(val){if(val)this.valueOf=this.toSource=this.toString=function(){return val};return val;};
function DownTown(){
var private=Object("You cant modify me");
this.get=function(){
return private;
}
this.export=function(callback){
callback(private);
}
}
var blackbox=new DownTown();
alert(blackbox.get());
blackbox.export(function(x){x.$("new val!")});
alert(blackbox.get());
function DownTown(){
var private=Object("You cant modify me");
this.get=function(){
return private;
}
this.export=function(callback){
callback(private);
}
}
var blackbox=new DownTown();
alert(blackbox.get());
blackbox.export(function(x){x.$("new val!")});
alert(blackbox.get());