referencia de variable javascript / alias

89

¿Es posible en javascript asignar un alias / referencia a una var local de alguna manera?

Me refiero a algo parecido a C:

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

= EDITAR =

¿Es posible asignar un alias a argumentos.callee en este código ?:

function foo() {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
  arguments.callee.myStaticVar++;
  return arguments.callee.myStaticVar;
}
gpilotino
fuente
5
La respuesta simple es no. Pero tengo la sensación de que alguien en SO vendrá con un truco para hacer esto :)
Amarghosh

Respuestas:

173

En JavaScript, los tipos primitivos, como los números enteros y las cadenas, se pasan por valor, mientras que los objetos se pasan por referencia. Entonces, para lograr esto, necesita usar un objeto:

// declare an object with property x
var obj = { x: 1 };
var aliasToObj = obj;
aliasToObj.x ++;
alert( obj.x ); // displays 2
Darin Dimitrov
fuente
eso fue rápido =) quiero hacer un alias para argumentos.callee dentro de mi función (solo para evitar escribir argumentos.callee cada vez). ¿Es esto posible con este método? Si lo entiendo, puedo alias "argumentos" pero todavía tengo que escribir "callee" de todos modos, ¿no es así?
gpilotino
9
@Darin: esto es un poco simplificado. Son tipos inmutables frente a mutables, en lugar de tipos primitivos frente a objetos. En JavaScript, todo es un objeto de alguna forma.
Crescent Fresh
7
En JS, la referencia se pasa por valor. Existe una diferencia entre "pasar-por-referencia" y "pasar-una-referencia-por-valor". En Javascript no se admite el paso de parámetros por referencia.
Corneliu
15

Hasta cierto punto, esto es posible, puede crear un alias para una variable usando cierres:

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 
usuario187291
fuente
1
Creo que "alerta (y); // imprime 2" debería ser: "alerta (y ()); // imprime 2" Tienes que llamar a la función para obtener el resultado. Lástima, ya que la sintaxis sugerida sería útil en determinadas situaciones.
Nathan Labenz
3
Esa redefinición de toString está ahí por una razón, así alert(y)que en realidad es correcta. Aunque redefinir los métodos de prototipos de funciones es de muy mal estilo. Pero bueno, ¡funciona!
metalim
8

Si puede alias algo depende del tipo de datos. Los objetos, matrices y funciones se manejarán por referencia y es posible crear un alias. Otros tipos son esencialmente atómicos y la variable almacena el valor en lugar de una referencia a un valor.

argumentos.callee es una función y, por lo tanto, puede tener una referencia a ella y modificar ese objeto compartido.

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

Tenga en cuenta que si en el código anterior dijera que self = function() {return 42;};entonces selfse referiría a un objeto diferente a arguments.callee, que sigue siendo una referencia a foo. Cuando tiene un objeto compuesto, el operador de asignación reemplaza la referencia, no cambia el objeto referido. Con valores atómicos, un caso como y++es equivalente a y = y + 1, que está asignando un 'nuevo' entero a la variable.

Sólo en el amor
fuente
sin mencionar que arguments.calleeya tiene un alias, que es el nombre de la función. En este ejemplo, podría usar foo.myStaticVar(¿tal vez este no era el caso en 2009?)
aljgom
1

editar a mi respuesta anterior: si desea contar las invocaciones de una función, es posible que desee probar:

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

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

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

Aquí, c sirve como contador y no es necesario utilizar argumentos.

Tom Bartel
fuente
o puede usar una variable estática countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom
1

Ampliando la publicación de user187291 , también puede usar getters / setters para evitar tener que usar funciones.

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'
Steven Jiménez
fuente
0

en 2019 necesito escribir complementos de jquery minificados, así que también lo necesito con este alias y, por lo tanto, probando estos ejemplos y otros, de otras fuentes, encontré una forma sin copiar en la memoria de todo el objeto, pero creando solo una referencia. Ya probé esto con Firefox y viendo la memoria de la pestaña del administrador de tareas en Firefox antes. El codigo es:

var {p: d} ={p: document};
console.log(d.body);
Constantin
fuente
Esto no pasa nada por referencia, simplemente puede pasar el documento directamente (que ya es una referencia a un objeto y se pasa por valor). La desestructuración no crea alias.
Recuerda a Monica