[javascript] Pointers in JavaScript?

Can we pass a reference of a variable that is immutable as argument in a function?

Example:

var x = 0;
function a(x)
{
    x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0

This question is related to javascript

The answer is


It just doesn't support pointers, end of story :-(.

I would like to add that, while I'm brand new and coming from a C background, from what I'm reading about the event loop and stack, you should keep whichever object as close to its caller as possible. As I'm brand new, I could have this wrong.

A lot of answers here suggest to make it global, but again if I'm reading correctly, that could possibly increase the stack hops and in a way, possibly fragment your event loop needlessly (depending on what the called object is currently doing) .

Also, any example given that mimics pointers, is just 1 in many ways to do the same thing, which will not be a pointer.


In JavaScript, you cannot pass variables by reference to a function. However you can pass an object by reference.


I'm thinking that in contrary to C or any language with pointers :

/** Javascript **/
var o = {x:10,y:20};
var o2 = {z:50,w:200};
  • obviously in javascript you cannot access to objects o and o2 addresses in memory
  • but you can't compare their address neither : (no trivial possibility to sort them, and then access by dichotomy)

.

o == o2 // obviously false : not the same address in memory
o <= o2 // true !
o >= o2 // also true !!

that's a huge problem :

  • it means that you can list/manage every objects created (allocated) by your application,

  • from that huge list of objects, compute some information about these (how they are linked together for example)

  • but when you want to retrieve the information you created about a specific object, you cannot find it in your huge list by dichotomy : there is no unique identifier per object that could be used as a replacement of the real memory address

this finally means that this is a huge problem, if you want to write in javascript :

  • a javascript debugger / IDE
  • or a specially optimized garbage collector
  • a data structure drawer / analyzer

This question may help: How to pass variable by reference in javascript? Read data from ActiveX function which returns more than one value

To summarise, Javascript primitive types are always passed by value, whereas the values inside objects are passed by reference (thanks to commenters for pointing out my oversight). So to get round this, you have to put your integer inside an object:

_x000D_
_x000D_
var myobj = {x:0};_x000D_
_x000D_
function a(obj)_x000D_
{_x000D_
    obj.x++;_x000D_
}_x000D_
_x000D_
a(myobj);_x000D_
alert(myobj.x); // returns 1_x000D_
_x000D_
  
_x000D_
_x000D_
_x000D_


Javascript should just put pointers into the mix coz it solves a lot of problems. It means code can refer to an unknown variable name or variables that were created dynamically. It also makes modular coding and injection easy.

This is what i see as the closest you can come to c pointers in practice

in js:

var a = 78;       // creates a var with integer value of 78 
var pointer = 'a' // note it is a string representation of the var name
eval (pointer + ' = 12'); // equivalent to: eval ('a = 12'); but changes value of a to 12

in c:

int a = 78;       // creates a var with integer value of 78 
int pointer = &a; // makes pointer  to refer to the same address mem as a
*pointer = 12;   // changes the value of a to 12

It might be impossible since JavaScript doesn't have Perl's "\" operator to get a primitive by reference, but there is a way to create an "effectively a pointer" object for a primitive using this pattern.

This solution makes the most sense for when you already have the primitive(so you can't put it into an object anymore without needing to modify other code), but still need to pass a pointer to it for other parts of your code to tinker with its state; so you can still tinker with its state using the seamless proxy which behaves like a pointer.

var proxyContainer = {};

// | attaches a pointer-lookalike getter/setter pair
// | to the container object.
var connect = function(container) {
    // | primitive, can't create a reference to it anymore
    var cant_touch_this = 1337;

    // | we know where to bind our accessor/mutator
    // | so we can bind the pair to effectively behave
    // | like a pointer in most common use cases.
    Object.defineProperty(container, 'cant_touch_this', {
        'get': function() {
            return cant_touch_this;
        },                
        'set': function(val) {
            cant_touch_this = val;
        }
    });
};

// | not quite direct, but still "touchable"
var f = function(x) {
    x.cant_touch_this += 1;
};

connect(proxyContainer);

// | looks like we're just getting cant_touch_this
// | but we're actually calling the accessor.
console.log(proxyContainer.cant_touch_this);

// | looks like we're touching cant_touch_this
// | but we're actually calling the mutator.
proxyContainer.cant_touch_this = 90;

// | looks like we touched cant_touch_this
// | but we actually called a mutator which touched it for us.
console.log(proxyContainer.cant_touch_this);

f(proxyContainer);

// | we kinda did it! :)
console.log(proxyContainer.cant_touch_this);

I have found a slightly different way implement pointers that is perhaps more general and easier to understand from a C perspective (and thus fits more into the format of the users example).

In JavaScript, like in C, array variables are actually just pointers to the array, so you can use an array as exactly the same as declaring a pointer. This way, all pointers in your code can be used the same way, despite what you named the variable in the original object.

It also allows one to use two different notations referring to the address of the pointer and what is at the address of the pointer.

Here is an example (I use the underscore to denote a pointer):

var _x = [ 10 ];

function foo(_a){
    _a[0] += 10;
}

foo(_x);

console.log(_x[0]);

Yields

output: 20

Late answer but I have come across a way of passing primitive values by reference by means of closures. It is rather complicated to create a pointer, but it works.

function ptr(get, set) {
    return { get: get, set: set };
}

function helloWorld(namePtr) {
    console.log(namePtr.get());
    namePtr.set('jack');
    console.log(namePtr.get())
}

var myName = 'joe';
var myNamePtr = ptr(
    function () { return myName; },
    function (value) { myName = value; }
);

helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack

In ES6, the code can be shortened to use lambda expressions:

var myName = 'joe';
var myNamePtr = ptr(=> myName, v => myName = v);

helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack

In your example you actually have 2 variables with the same name. The (global) variable x and the function scoped variable x. Interesting to see that javascript, when given a choice of what to do with 2 variables of the same name, goes with the function scoped name and ignores the out-of-scope variable.

It's probably not safe to presume javascript will always behave this way...

Cheers!


JavaScript doesn't support passing primitive types by reference. There is a workaround, though.

Put all the variables you need to pass in an object. In this case, there's only one variable, x. Instead of passing the variable, pass the variable name as a string, which is "x".

_x000D_
_x000D_
var variables = {x:0};_x000D_
function a(x)_x000D_
{_x000D_
    variables[x]++;_x000D_
}_x000D_
a("x");_x000D_
alert(variables.x);
_x000D_
_x000D_
_x000D_


In JavaScript that would be a global. However, your function would look more like this:

function a(){
   x++;
};

Since x is in the global context, you don't need to pass it into the function.


You refer to 'x' from window object

var x = 0;

function a(key, ref) {
    ref = ref || window;  // object reference - default window
    ref[key]++;
}

a('x');                   // string
alert(x);

Depending on what you would like to do, you could simply save the variable name, and then access it later on like so:

function toAccessMyVariable(variableName){
  alert(window[variableName]);
}

var myFavoriteNumber = 6; 

toAccessMyVariable("myFavoriteNumber");

To apply to your specific example, you could do something like this:

var x = 0;
var pointerToX = "x";

function a(variableName)
{
    window[variableName]++;
}
a(pointerToX);
alert(x); //Here I want to have 1 instead of 0