Können wir eine Referenz einer Variablen übergeben, die als Argument in einer Funktion unveränderlich ist?
Beispiel:
var x = 0;
function a(x)
{
x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0
Können wir eine Referenz einer Variablen übergeben, die als Argument in einer Funktion unveränderlich ist?
Beispiel:
var x = 0;
function a(x)
{
x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0
Antworten:
Da JavaScript die Übergabe von Parametern als Referenz nicht unterstützt, müssen Sie die Variable stattdessen zu einem Objekt machen:
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 diesem Fall xhandelt es sich um eine Referenz auf ein Objekt. Wenn xan die Funktion übergeben wird a, wird diese Referenz in kopiert obj. Also, objund xbeziehen sich auf das gleiche im Gedächtnis. Das Ändern der ValueEigenschaft von objwirkt sich auf die ValueEigenschaft von aus x.
Javascript übergibt Funktionsparameter immer als Wert. Das ist einfach eine Spezifikation der Sprache. Sie könnenx in einem für beide Funktionen lokalen Bereich erstellen und die Variable überhaupt nicht übergeben.
Diese Frage kann helfen: Wie übergebe ich eine Variable als Referenz in Javascript? Lesen Sie Daten aus der ActiveX-Funktion, die mehr als einen Wert zurückgibt
Zusammenfassend lässt sich sagen, dass primitive Javascript-Typen immer als Wert übergeben werden, während die Werte in Objekten als Referenz übergeben werden (danke an Kommentatoren, die auf mein Versehen hingewiesen haben). Um dies zu umgehen, müssen Sie Ihre Ganzzahl in ein Objekt einfügen:
var myobj = {x:0};
function a(obj)
{
obj.x++;
}
a(myobj);
alert(myobj.x); // returns 1
xWert übergeben, unabhängig davon, ob xes sich um ein Objekt handelt oder nicht, können Sie es nicht durch einen ganz anderen Wert ersetzen, wie es der Aufrufer sehen wird.
Ich habe einen etwas anderen Weg gefunden, Zeiger zu implementieren, der vielleicht allgemeiner und aus C-Sicht leichter zu verstehen ist (und daher besser in das Format des Benutzerbeispiels passt).
In JavaScript sind Array-Variablen wie in C eigentlich nur Zeiger auf das Array, sodass Sie ein Array genauso verwenden können wie das Deklarieren eines Zeigers. Auf diese Weise können alle Zeiger in Ihrem Code auf dieselbe Weise verwendet werden, obwohl Sie die Variable im ursprünglichen Objekt benannt haben.
Es erlaubt auch, zwei verschiedene Notationen zu verwenden, die sich auf die Adresse des Zeigers und die Adresse des Zeigers beziehen.
Hier ist ein Beispiel (ich benutze den Unterstrich, um einen Zeiger zu bezeichnen):
var _x = [ 10 ];
function foo(_a){
_a[0] += 10;
}
foo(_x);
console.log(_x[0]);
Erträge
output: 20
Späte Antwort, aber ich bin auf eine Möglichkeit gestoßen, primitive Werte durch Verweise durch Verschlüsse zu übergeben. Es ist ziemlich kompliziert, einen Zeiger zu erstellen, aber es funktioniert.
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 kann der Code gekürzt werden, um Lambda-Ausdrücke zu verwenden:
var myName = 'joe';
var myNamePtr = ptr(=> myName, v => myName = v);
helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack
In JavaScript wäre das ein globaler. Ihre Funktion würde jedoch eher so aussehen:
function a(){
x++;
};
Da xes sich um einen globalen Kontext handelt, müssen Sie ihn nicht an die Funktion übergeben.
Javascript sollte nur Zeiger in die Mischung einfügen, da es viele Probleme löst. Dies bedeutet, dass Code auf einen unbekannten Variablennamen oder auf Variablen verweisen kann, die dynamisch erstellt wurden. Es macht auch die modulare Codierung und Injektion einfach.
Dies ist das, was ich als das Beste sehe, was man in der Praxis an c Zeigern erreichen kann
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
Es ist möglicherweise unmöglich, da JavaScript nicht über den Perl-Operator "\" verfügt, um ein Grundelement als Referenz abzurufen. Es gibt jedoch eine Möglichkeit, mithilfe dieses Musters ein "effektiv ein Zeiger" -Objekt für ein Grundelement zu erstellen.
Diese Lösung ist am sinnvollsten, wenn Sie das Grundelement bereits haben (Sie können es also nicht mehr in ein Objekt einfügen, ohne anderen Code ändern zu müssen), aber dennoch einen Zeiger darauf übergeben müssen, damit andere Teile Ihres Codes basteln können mit seinem Zustand; Sie können also weiterhin mit dem nahtlosen Proxy, der sich wie ein Zeiger verhält, an seinem Status basteln.
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 können Sie keine Variablen als Referenz auf eine Funktion übergeben. Sie können ein Objekt jedoch als Referenz übergeben.
Ich denke, dass im Gegensatz zu C oder einer Sprache mit Zeigern:
/** 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 !!
Das ist ein großes Problem:
Dies bedeutet, dass Sie alle von Ihrer Anwendung erstellten (zugewiesenen) Objekte auflisten / verwalten können.
Berechnen Sie aus dieser riesigen Liste von Objekten einige Informationen über diese (wie sie zum Beispiel miteinander verknüpft sind).
Wenn Sie jedoch die Informationen abrufen möchten, die Sie über ein bestimmtes Objekt erstellt haben, können Sie diese nicht durch Dichotomie in Ihrer großen Liste finden : Es gibt keine eindeutige Kennung pro Objekt , die als Ersatz für die reale Speicheradresse verwendet werden könnte
Dies bedeutet schließlich, dass dies ein großes Problem ist, wenn Sie in Javascript schreiben möchten:
JavaScript unterstützt nicht die Übergabe primitiver Typen als Referenz. Es gibt jedoch eine Problemumgehung.
Fügen Sie alle Variablen, die Sie übergeben müssen, in ein Objekt ein. In diesem Fall gibt es nur eine Variable x. Anstatt die Variable zu übergeben, übergeben Sie den Variablennamen als Zeichenfolge "x".
var variables = {x:0};
function a(x)
{
variables[x]++;
}
a("x");
alert(variables.x);
Je nachdem, was Sie tun möchten, können Sie den Variablennamen einfach speichern und später wie folgt darauf zugreifen:
function toAccessMyVariable(variableName){
alert(window[variableName]);
}
var myFavoriteNumber = 6;
toAccessMyVariable("myFavoriteNumber");
Um sich auf Ihr spezielles Beispiel zu beziehen, können Sie Folgendes tun:
var x = 0;
var pointerToX = "x";
function a(variableName)
{
window[variableName]++;
}
a(pointerToX);
alert(x); //Here I want to have 1 instead of 0
windowobjektspezifisch. Es wird auch weniger empfohlen, globale Variablen zu verwenden, da möglicherweise bereits eine Variable mit demselben Namen vorhanden ist.
Es unterstützt nur keine Zeiger, Ende der Geschichte :-(.
Ich möchte hinzufügen, dass Sie, obwohl ich brandneu bin und einen C-Hintergrund habe, nach dem, was ich über die Ereignisschleife und den Stapel lese, jedes Objekt so nah wie möglich an seinem Aufrufer halten sollten. Da ich brandneu bin, könnte ich das falsch machen.
Viele Antworten hier schlagen vor, es global zu machen, aber wenn ich richtig lese, könnte dies möglicherweise die Stapelsprünge erhöhen und in gewisser Weise Ihre Ereignisschleife unnötig fragmentieren (abhängig davon, was das aufgerufene Objekt gerade tut).
Außerdem ist jedes Beispiel, das Zeiger nachahmt, in vielerlei Hinsicht nur 1, um dasselbe zu tun, was kein Zeiger sein wird.
Nein, du kannst nicht. Der Browser gewährt Ihnen keinen Zugriff auf den Systemspeicher und seine Variablen. Es sollte mit einer Umgebung wie einem Knoten möglich sein, aber im Browser ist dies nur möglich, wenn Sie ein Hacker sind.
In Ihrem Beispiel haben Sie tatsächlich 2 Variablen mit demselben Namen. Die (globale) Variable x und die Variable x mit Funktionsbereich . Es ist interessant zu sehen, dass Javascript, wenn es die Wahl hat, was mit zwei gleichnamigen Variablen zu tun ist, zum Funktionsbereichsnamen passt und die Variable außerhalb des Gültigkeitsbereichs ignoriert.
Es ist wahrscheinlich nicht sicher anzunehmen, dass sich Javascript immer so verhält ...
Prost!
var x = 0; Funktion a () {x ++; } a (x); console.log (x);