93

Is it possible in javascript to assign an alias/reference to a local var someway?

I mean something C-like:

function foo() {
  var x = 1;
  var y = &x;
  y++;
  alert(x); // prints 2 
}

= EDIT =

Is it possible to alias arguments.callee in this code?:

function foo() {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
  arguments.callee.myStaticVar++;
  return arguments.callee.myStaticVar;
}
Damian Green
  • 6,895
  • 2
  • 31
  • 43
gpilotino
  • 13,055
  • 9
  • 48
  • 61

6 Answers6

174

In JavaScript, primitive types such as integers and strings are passed by value whereas objects are passed by reference. So in order to achieve this you need to use an object:

// declare an object with property x
var obj = { x: 1 };
var aliasToObj = obj;
aliasToObj.x ++;
alert( obj.x ); // displays 2
Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • that was fast =) i want to make an alias to arguments.callee inside my function (just to avoid typing arguments.callee every time). is this possibile with this method ? If I understand, I can alias "arguments" but I still have to write "callee" anyway, isn't it ? – gpilotino Nov 06 '09 at 11:35
  • 11
    @Darin: this is a bit oversimplifying it. It's immutable vs mutable types, rather than primitive types vs objects. In JavaScript everything is an object in some form. – Crescent Fresh Nov 06 '09 at 12:16
  • 9
    In JS the reference is passed by value. There is a difference between "passing-by-reference" and "passing-a-reference-by-value". In Javascript passing of parameters by reference is not suported. – Corneliu Sep 20 '12 at 16:22
  • 1
    ^^ this. The answer is misleading. Passing object references is **not** an example of call-by-reference. – trincot Feb 26 '22 at 09:15
14

To some degree this is possible, you can create an alias to a variable using closures:

Function.prototype.toString = function() {
    return this();
}

var x = 1;
var y = function() { return x }
x++;
alert(y); // prints 2, no need for () because of toString redefinition 
Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
user187291
  • 53,363
  • 19
  • 95
  • 127
  • 1
    I believe "alert(y); // prints 2" should be: "alert(y()); // prints 2" You have to actually call the function to get the result. Too bad, as the suggested syntax would be helpful in certain situations. – Nathan Labenz Apr 24 '13 at 23:11
  • 3
    That toString re-definition is there for a reason, so `alert(y)` is actually right. Although redefining Function prototype methods is very bad style. But hey, it works! – metalim Feb 09 '16 at 08:04
8

Whether you can alias something depends on the data type. Objects, arrays, and functions will be handled by reference and aliasing is possible. Other types are essentially atomic, and the variable stores the value rather than a reference to a value.

arguments.callee is a function, and therefore you can have a reference to it and modify that shared object.

function foo() {
  var self = arguments.callee;
  self.myStaticVar = self.myStaticVar || 0;
  self.myStaticVar++;
  return self.myStaticVar;
}

Note that if in the above code you were to say self = function() {return 42;}; then self would then refer to a different object than arguments.callee, which remains a reference to foo. When you have a compound object, the assignment operator replaces the reference, it does not change the referred object. With atomic values, a case like y++ is equivalent to y = y + 1, which is assigning a 'new' integer to the variable.

Justin Love
  • 4,397
  • 25
  • 36
  • not to mention that `arguments.callee` already has an alias, which is the name of the function. In this example you could just use `foo.myStaticVar` (maybe this wasn't the case back in 2009?) – aljgom Mar 14 '17 at 18:27
2

Expanding on user187291's post, you could also use getters/setters to get around having to use functions.

var x = 1;
var ref = {
    get x()  { return x; },
    set x(v) { x = v; }
};
(ref.x)++;
console.log(x); // prints '2'
x--;
console.log(ref.x); // prints '1'
Community
  • 1
  • 1
1

edit to my previous answer: if you want to count a function's invocations, you might want to try:

var countMe = ( function() {
  var c = 0;

  return function() {
    c++;
    return c;
  }
})();

alert(countMe()); // Alerts "1"
alert(countMe()); // Alerts "2"

Here, c serves as the counter, and you do not have to use arguments.callee.

Tom Bartel
  • 2,283
  • 1
  • 15
  • 18
1

in 2019 I need to write minified jquery plugins so I need it too this alias and so testing these examples and others ,from other sources,I found a way without copy in the memory of whe entire object ,but creating only a reference. I tested this already with firefox and watching task manager's tab memory on firefox before. The code is:

var {p: d} ={p: document};
console.log(d.body);
  • This doesn't pass anything by reference, you can just pass document directly (which already is a reference to an object, and is passed by value). The destructuring does not create aliases. – Remember Monica Sep 30 '19 at 05:39