Since the only thing you're using the pointer for is to dereference it to access another variable, you can just encapsulate it in a property.
function createPointer(read, write) {
return { get value() { return read(); }, set value(v) { return write(v); } };
}
To create a pointer, pass the accessor methods which read and write the variable being pointed to.
var i;
var p = createPointer(function() { return i; }, function(v) { i = v; });
// p is now a "pointer" to i
To dereference a pointer, access its value. In other words, where in C you would write *p
here you write p.value
.
i = "initial";
alert(p.value); // alerts "initial"
p.value = "update";
alert(i); // alerts "update"
p.value += "2";
alert(i); // alerts "update2"
You can create multiple pointers to the same variable.
var q = createPointer(function() { return i; }, function(v) { i = v; });
// q is also a "pointer" to i
alert(q.value); // alerts "update2"
q.value = "written from q";
alert(p.value); // alerts "written from q"
You can change what a pointer points to by simply overwriting the pointer variable with another pointer.
var j = "other";
q = createPointer(function() { return j; }, function(v) { j = v; });
// q is now a "pointer" to j
You can swap two variables through pointers.
function swap(x, y) {
var t = x.value;
x.value = y.value;
y.value = t;
}
Let's swap the values of i
and j
by using their pointers.
swap(p, q);
alert(i); // alerts "other"
alert(j); // alerts "written from q"
You can create pointers to local variables.
function example() {
var myVar = "myVar as local variable from example";
var r = createPointer(function() { return myVar; }, function(v) { myVar = v; });
swap(p,r);
alert(i); // alerts "myVar as local variable from example"
alert(myVar); // alerts "other"
}
example();
Through the magic of closures, this gives you a way to simulate malloc.
function malloc() {
var i;
return createPointer(function() { return i; }, function(v) { i = v; });
}
var p = malloc(); // p points to a variable we just allocated from the heap
p.value = 2; // write a 2 into it
Your magic trick works too:
var flowers = new Misdirection(
createPointer(function() { return flowers; }, function(v) { flowers = v; }));
flowers.abracadabra();
alert(flowers);
function Misdirection(flowers) {
this.abracadabra = function() {
flowers.value = new Rabbit;
};
}
function Rabbit() {
this.toString = function() { return "Eh... what's up doc?" };
}