¿Podemos pasar una referencia de una variable que sea inmutable como argumento en una función?
Ejemplo:
var x = 0;
function a(x)
{
x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0
javascript
usuario1342369
fuente
fuente
Respuestas:
Dado que JavaScript no admite el paso de parámetros por referencia, deberá convertir la variable en un objeto:
var x = {Value: 0}; function a(obj) { obj.Value++; } a(x); document.write(x.Value); //Here i want to have 1 instead of 0
En este caso,
x
es una referencia a un objeto. Cuandox
se pasa a la funcióna
, esa referencia se copia aobj
. Así,obj
y sex
refieren a lo mismo en la memoria. Cambiar laValue
propiedad deobj
afecta laValue
propiedad dex
.Javascript siempre pasará los parámetros de función por valor. Eso es simplemente una especificación del idioma. Usted podría crear
x
en un ámbito local para ambas funciones, y no pasar la variable en absoluto.fuente
Esta pregunta puede ayudar: ¿Cómo pasar variables por referencia en javascript? Leer datos de la función ActiveX que devuelve más de un valor
Para resumir, los tipos primitivos de Javascript siempre se pasan por valor, mientras que los valores dentro de los objetos se pasan por referencia (gracias a los comentaristas por señalar mi descuido). Entonces, para evitar esto, debes poner tu número entero dentro de un objeto:
var myobj = {x:0}; function a(obj) { obj.x++; } a(myobj); alert(myobj.x); // returns 1
fuente
x
por valor, yax
sea un objeto o no, no puede reemplazarlo con un valor completamente diferente de cualquier manera que vea la persona que llama.He encontrado una forma ligeramente diferente de implementar punteros que es quizás más general y más fácil de entender desde una perspectiva de C (y por lo tanto encaja más en el formato del ejemplo de los usuarios).
En JavaScript, como en C, las variables de matriz son en realidad solo punteros a la matriz, por lo que puede usar una matriz exactamente igual que declarar un puntero. De esta manera, todos los punteros en su código se pueden usar de la misma manera, a pesar del nombre de la variable en el objeto original.
También permite usar dos notaciones diferentes que se refieren a la dirección del puntero y lo que está en la dirección del puntero.
Aquí hay un ejemplo (uso el guión bajo para indicar un puntero):
var _x = [ 10 ]; function foo(_a){ _a[0] += 10; } foo(_x); console.log(_x[0]);
Rendimientos
output: 20
fuente
Te refieres a 'x' del objeto de la ventana
var x = 0; function a(key, ref) { ref = ref || window; // object reference - default window ref[key]++; } a('x'); // string alert(x);
fuente
Respuesta tardía, pero me he encontrado con una forma de pasar valores primitivos por referencia mediante cierres. Es bastante complicado crear un puntero, pero funciona.
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
En ES6, el código se puede acortar para usar expresiones lambda:
var myName = 'joe'; var myNamePtr = ptr(=> myName, v => myName = v); helloWorld(myNamePtr); // joe, jack console.log(myName); // jack
fuente
En JavaScript, eso sería global. Sin embargo, su función se parecería más a esto:
function a(){ x++; };
Como
x
está en el contexto global, no es necesario pasarlo a la función.fuente
Javascript debería poner punteros en la mezcla porque resuelve muchos problemas. Significa que el código puede hacer referencia a un nombre de variable desconocido o variables que se crearon dinámicamente. También facilita la codificación modular y la inyección.
Esto es lo que veo como lo más cerca que puede llegar a los punteros c en la práctica
en 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
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
fuente
Puede ser imposible ya que JavaScript no tiene el operador "\" de Perl para obtener una primitiva por referencia, pero hay una manera de crear un objeto "efectivamente un puntero" para una primitiva usando este patrón.
Esta solución tiene más sentido para cuando ya tiene el primitivo (por lo que ya no puede ponerlo en un objeto sin necesidad de modificar otro código), pero aún necesita pasarle un puntero para que otras partes de su código lo modifiquen. con su estado; por lo que aún puede jugar con su estado utilizando el proxy transparente que se comporta como un puntero.
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);
fuente
En JavaScript, no puede pasar variables por referencia a una función. Sin embargo, puede pasar un objeto por referencia.
fuente
Estoy pensando que, al contrario de C o cualquier idioma con punteros:
/** 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 !!
eso es un gran problema:
significa que puede enumerar / administrar todos los objetos creados (asignados) por su aplicación,
a partir de esa enorme lista de objetos, calcule alguna información sobre estos (cómo están vinculados, por ejemplo)
pero cuando desea recuperar la información que creó sobre un objeto específico, no puede encontrarla en su enorme lista por dicotomía: no hay un identificador único por objeto que pueda usarse como reemplazo de la dirección de memoria real
esto finalmente significa que este es un gran problema, si desea escribir en javascript:
fuente
JavaScript no admite el paso de tipos primitivos por referencia. Sin embargo, hay una solución.
Pon todas las variables que necesitas para pasar en un objeto. En este caso, sólo hay una variable
x
. En lugar de pasar la variable, pase el nombre de la variable como una cadena, que es"x"
.var variables = {x:0}; function a(x) { variables[x]++; } a("x"); alert(variables.x);
fuente
Dependiendo de lo que le gustaría hacer, simplemente puede guardar el nombre de la variable y luego acceder a él más adelante así:
function toAccessMyVariable(variableName){ alert(window[variableName]); } var myFavoriteNumber = 6; toAccessMyVariable("myFavoriteNumber");
Para aplicar a su ejemplo específico, podría hacer algo como esto:
var x = 0; var pointerToX = "x"; function a(variableName) { window[variableName]++; } a(pointerToX); alert(x); //Here I want to have 1 instead of 0
fuente
window
objeto. Además, es menos recomendable utilizar variables globales, ya que podría haber una variable con el mismo nombre.Simplemente no admite punteros, fin de la historia :-(.
Me gustaría agregar que, aunque soy nuevo y provengo de un entorno C, por lo que estoy leyendo sobre el bucle de eventos y la pila, debe mantener el objeto lo más cerca posible de su llamador. Como soy nuevo, podría equivocarme.
Muchas respuestas aquí sugieren que sea global, pero nuevamente, si estoy leyendo correctamente, eso posiblemente podría aumentar los saltos de pila y, de alguna manera, posiblemente fragmentar su bucle de eventos innecesariamente (dependiendo de lo que el objeto llamado esté haciendo actualmente).
Además, cualquier ejemplo dado que imita punteros, es solo 1 en muchas formas para hacer lo mismo, que no será un puntero.
fuente
En su ejemplo, en realidad tiene 2 variables con el mismo nombre. La variable (global) x y la función dentro del ámbito variable de x. Es interesante ver que javascript, cuando se le da la opción de qué hacer con 2 variables del mismo nombre, va con el nombre del ámbito de la función e ignora la variable fuera del ámbito.
Probablemente no sea seguro suponer que javascript siempre se comportará de esta manera ...
¡Salud!
fuente
No, no puedes. El navegador no le da acceso a la memoria del sistema y sus variables. Debería ser posible con un entorno como un nodo, pero dentro del navegador no es posible a menos que sea un hacker.
fuente