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
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
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.
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:
var myobj = {x:0};
function a(obj)
{
obj.x++;
}
a(myobj);
alert(myobj.x); // returns 1
x
by value, whether x
is an object or not, you can't replace it with a whole other value in any way the caller will see. –
Wapiti 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
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);
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
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
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.
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);
In JavaScript, you cannot pass variables by reference to a function. However you can pass an object by reference.
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!
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};
.
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 :
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);
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
window
object. Also, it is less recommended to use global variables, since there might already be a variable with the same name. –
Colonial 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.
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);
© 2022 - 2024 — McMap. All rights reserved.