Pointers in JavaScript?

Javascript

Javascript Problem Overview


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

Javascript Solutions


Solution 1 - 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

In this case, x is a reference to an object. When x is passed to the function a, that reference is copied over to obj. Thus, obj and x refer to the same thing in memory. Changing the Value property of obj affects the Value property of x.

Javascript will always pass function parameters by value. That's simply a specification of the language. You could create x in a scope local to both functions, and not pass the variable at all.

Solution 2 - Javascript

This question may help: https://stackoverflow.com/questions/1732557/how-to-pass-variable-by-reference-in-javascript-read-data-from-activex-function

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:

var myobj = {x:0};

function a(obj)
{
    obj.x++;
}

a(myobj);
alert(myobj.x); // returns 1

Solution 3 - Javascript

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

Solution 4 - Javascript

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);

Solution 5 - Javascript

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:

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(() => myName, v => myName = v);

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

Solution 6 - Javascript

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

Solution 7 - Javascript

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.

Solution 8 - Javascript

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);

Solution 9 - Javascript

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

Solution 10 - Javascript

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

Solution 11 - Javascript

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".

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

Solution 12 - Javascript

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

Solution 13 - Javascript

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.

Solution 14 - Javascript

I'll agree with the most quotet answer, but please be aware from 'var' argument, use 'let', or better in this case 'const', because the pointer, or the pointing object shouldn`t be change anytime.

const x = {value: 0};

function foo(obj){
  ++obj.value;
}

foo(x);
alert(x.value);

Solution 15 - Javascript

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!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1342369View Question on Stackoverflow
Solution 1 - JavascriptMike ChristensenView Answer on Stackoverflow
Solution 2 - Javascriptn00dleView Answer on Stackoverflow
Solution 3 - JavascriptWilliam OliverView Answer on Stackoverflow
Solution 4 - JavascriptAlexisKView Answer on Stackoverflow
Solution 5 - JavascriptHimanshuView Answer on Stackoverflow
Solution 6 - JavascriptEmmanuel MahuniView Answer on Stackoverflow
Solution 7 - JavascriptMaessView Answer on Stackoverflow
Solution 8 - JavascriptDmitryView Answer on Stackoverflow
Solution 9 - Javascriptd4rkpr1nc3View Answer on Stackoverflow
Solution 10 - JavascriptreunsView Answer on Stackoverflow
Solution 11 - JavascriptclickbaitView Answer on Stackoverflow
Solution 12 - JavascriptLionessView Answer on Stackoverflow
Solution 13 - Javascriptuser10741425View Answer on Stackoverflow
Solution 14 - JavascriptPeter WochingerView Answer on Stackoverflow
Solution 15 - JavascripttpaytnView Answer on Stackoverflow