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

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

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 

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.


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.


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'

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.