Pointers in JavaScript

Are there pointers in javascript?

No, JS doesn't have pointers.

Objects are passed around by passing a copy of a reference. The programmer cannot access any C-like "value" representing the address of an object.

Within a function, one may change the contents of a passed object via that reference, but you cannot modify the reference that the caller had because your reference is only a copy:

var foo = {'bar': 1};

function tryToMungeReference(obj) {
obj = {'bar': 2}; // won't change caller's object
}

function mungeContents(obj) {
obj.bar = 2; // changes _contents_ of caller's object
}

tryToMungeReference(foo);
foo.bar === 1; // true - foo still references original object

mungeContents(foo);
foo.bar === 2; // true - object referenced by foo has been modified

Pointers in JavaScript?

Since JavaScript does not support passing parameters by reference, you'll need to make the variable an object instead:

var x = {Value: 0};
function a(obj){ obj.Value++;}
a(x);document.write(x.Value); //Here i want to have 1 instead of 0

How to create a pointer in JavaScript

There are no pointers in the JavaScript language.

Every variable that contains an Object is actually an opaque reference to that object.

Within the interpreter that reference will take the form of a pointer, but the value of that pointer is not accessible to you.

How to simulate pointers in JavaScript?

Needless to say, but JavaScript does not have a general mechanism to pass arguments by reference.

There can be some confusion around the term "reference", as in JavaScript one can pass objects to functions -- which are references -- but this is a call-by-value mechanism. Call-by-reference really means that the parameter variable is an alias for the caller's variable, such that assigning to that alias is equivalent to assigning to the caller's variable. Except for some very particular situations (like the arguments exotic object in non-strict mode, or the export mechanism, or the var link with the window object, none of which helps you in your case in a best practice way), there is no such variable-aliasing mechanism in JavaScript.

Here is an example on how to "exploit" the effect of var in a browser context, in non-strict mode:

function modify(ref) {
// Using the fact that global `var` variables are aliases
// for properties on the global object
// (This is not considered good practice)
globalThis[ref] = globalThis[ref] + 1;
}

var a = 1;
modify("a"); // We pass a reference to `a`
console.log(a);

Is there a better way to simulate pointers in JavaScript?

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?" };
}

Javascript linked list implementation and pointers

You clarified your question in the comments.

The answer has to do with variable binding vs values.

JavaScript has internal representations for values like strings, numbers, user defined objects, and so on. That representation is the same whether or not the value is named foo, or is buried deep in some data structure.

Programs have variables. At any moment in time, a given variable is bound to a given value. This gives programmers a way to tell JavaScript what should happen to the values that they are bound to.

Assignment is binding values to things. When we assign to a variable, it is no longer bound to whatever old value it has been bound to. That old value may still exist in some data structure, or may become garbage to be cleaned up. But it is no longer associated with that variable.

And so here is what the sample code that you gave actually does.

-- Create a value and bind it to head.
let head = {
value: 2,
next: null
};
/* CURRENT BINDING:
*
* head ----> {value:2, next:null}
*/

-- Create a value and bind it to newObj
let newObj = {
value: 1,
next: head
};
/* CURRENT BINDING:
*
* newObj ----> {value:1, next:
* head ----> {value:2, next:null}
* }
*/

-- Bind the variable head to the value newObj is bound to.
head = newObj;
/* CURRENT BINDING:
*
* head,newObj
* ----> {value:1, next:
* {value:2, next:null}
* }
*/

-- And see that it worked.
console.log(head)

Does that clarify your model of how programs represent data enough to understand why this code doesn't create a circular reference?

But if you're curious, it is possible to create circular references.

let foo = {value:1}:
foo['next'] = foo;
console.log(foo);

How did that work, isn't assignment just binding values to things? Well, yes. But if the thing that it is bound to is somewhere in a data structure, then that data structure had to get changed to allow it to be bound.

What happens after you create circular references varies by language. In JavaScript, at some point after it is bound to nothing, the garbage collector will clean it up. In Python, it takes on a life of its own and you leak memory. And so on.

Javascript Function-Pointer Assignment

Yes that is expected and by design.

Your question is basically: does foo reference bar as a pointer or reference would in another language?

The answer is no: the value of bar at the time of assignment is assigned to foo.



Related Topics



Leave a reply



Submit