477 Stimmen

Kann JavaScript per Verweis übergeben werden?

Wird JavaScript durch Referenzen oder durch Werte weitergegeben?

Hier ist ein Beispiel aus _JavaScript: Die guten Seiten_ . Ich bin sehr verwirrt über die my Parameter für die Funktion Rechteck. Er ist eigentlich undefined und innerhalb der Funktion neu definiert. Es gibt keine ursprüngliche Referenz. Wenn ich sie aus dem Funktionsparameter entferne, kann die Funktion innerhalb des Bereichs nicht darauf zugreifen.

Ist es ein Abschluss? Aber es wird keine Funktion zurückgegeben.

var shape = function (config) {
    var that = {};
    that.name = config.name || "";
    that.area = function () {
        return 0;
    };
    return that;
};

var rectangle = function (config, my) {
    my = my || {};
    my.l = config.length || 1;
    my.w = config.width || 1;
    var that = shape(config);
    that.area = function () {
        return my.l * my.w;
    };
    return that;
};

myShape = shape({
    name: "Unhnown"
});

myRec = rectangle({
    name: "Rectangle",
    length: 4,
    width: 6
});

console.log(myShape.name + " area is " + myShape.area() + " " + myRec.name + " area is " + myRec.area());

875voto

Alnitak Punkte 324207

Primitive werden als Wert und Objekte als "Kopie einer Referenz" übergeben.

Wenn Sie ein Objekt (oder Array) übergeben, übergeben Sie (unsichtbar) einen Verweis auf dieses Objekt, und es ist möglich, die Inhalt dieses Objekts, aber wenn Sie versuchen, den Verweis zu überschreiben, wirkt sich dies nicht auf die Kopie des Verweises im Besitz des Aufrufers aus - d.h. der Verweis selbst wird als Wert übergeben:

function replace(ref) {
    ref = {};           // this code does _not_ affect the object passed
}

function update(ref) {
    ref.key = 'newvalue';  // this code _does_ affect the _contents_ of the object
}

var a = { key: 'value' };
replace(a);  // a still has its original value - it's unmodfied
update(a);   // the _contents_ of 'a' are changed

73voto

jAndy Punkte 223172

Stellen Sie sich das folgendermaßen vor:

Wann immer Sie eine Objekt in ECMAscript wird dieses Objekt in einer Mystique gebildet ECMAscript Universalplatz wo kein Mensch jemals hinkommen wird. Alles, was man zurückbekommt, ist ein Referenz zu diesem Objekt an diesem mystischen Ort.

var obj = { };

Sogar obj ist nur ein Verweis auf das Objekt (das sich an diesem speziellen wunderbaren Ort befindet) und daher können Sie nur dieses Referenz herum. Effektiv kann jedes Stück Code, das auf obj wird die Objekt die weit, weit weg ist.

41voto

Funktionsargumente werden entweder als Wert oder als Teilung übergeben, aber niemals immer durch Verweis in JavaScript!

Call-by-Value

Primitive Typen werden by-value übergeben:

var num = 123, str = "foo";

function f(num, str) {
  num += 1;
  str += "bar";
  console.log("inside of f:", num, str);
}

f(num, str);
console.log("outside of f:", num, str);

Neuzuweisungen innerhalb eines Funktionsbereichs sind im umgebenden Bereich nicht sichtbar.

Dies gilt auch für String s, die einen zusammengesetzten Datentyp darstellen und dennoch unveränderlich sind:

var str = "foo";

function f(str) {
  str[0] = "b"; // doesn't work, because strings are immutable
  console.log("inside of f:", str);
}

f(str);
console.log("outside of f:", str);

Call-by-Sharing

Objekte, d. h. alle Typen, die keine Primitiven sind, werden durch gemeinsame Nutzung übergeben. Eine Variable, die einen Verweis auf ein Objekt enthält, enthält eigentlich nur eine Kopie dieses Verweises. Würde JavaScript eine Call-by-Reference Bewertungsstrategie würde die Variable die ursprüngliche Referenz enthalten. Dies ist der entscheidende Unterschied zwischen by-sharing und by-reference.

Was sind die praktischen Konsequenzen dieser Unterscheidung?

var o = {x: "foo"}, p = {y: 123};

function f(o, p) {
  o.x = "bar"; // Mutation
  p = {x: 456}; // Reassignment
  console.log("o inside of f:", o);
  console.log("p inside of f:", p);
}

f(o, p);

console.log("o outside of f:", o);
console.log("p outside of f:", p);

Mutation bedeutet, bestimmte Eigenschaften eines bestehenden Object . Die Referenzkopie, an die eine Variable gebunden ist und die sich auf dieses Objekt bezieht, bleibt gleich. Mutationen sind also im Bereich des Aufrufers sichtbar.

Neuzuweisung bedeutet, dass die an eine Variable gebundene Referenzkopie ersetzt wird. Da es sich nur um eine Kopie handelt, bleiben andere Variablen, die eine Kopie derselben Referenz enthalten, davon unberührt. Neuzuweisungen sind daher im Bereich des Aufrufers nicht sichtbar, wie es bei einer Call-by-Reference Bewertungsstrategie.

Weitere Informationen über Bewertungsstrategien in ECMAScript.

22voto

jmoreno Punkte 13076

Wie bei C wird letztlich alles als Wert übergeben. Im Gegensatz zu C können Sie nicht wirklich zurückgehen und den Ort einer Variablen übergeben, da es keine Zeiger, sondern nur Referenzen gibt.

Und die Verweise, die es hat, sind alle auf Objekte, nicht auf Variablen. Es gibt mehrere Möglichkeiten, das gleiche Ergebnis zu erzielen, aber sie müssen von Hand gemacht werden, nicht nur durch Hinzufügen eines Schlüsselworts entweder beim Aufruf oder bei der Deklaration.

9voto

yallam Punkte 1116

JavaScript ist eine Wertübergabe.

Bei Primitiven wird der Wert des Primitivs übergeben. Bei Objekten wird die Objektreferenz "value" übergeben.

Beispiel mit Objekt:

var f1 = function(inputObject){
    inputObject.a = 2;
}

var f2 = function(){
    var inputObject = {"a": 1};
    f1(inputObject);
    console.log(inputObject.a);
}

Der Aufruf von f2 führt dazu, dass der Wert "a" als 2 statt als 1 ausgedruckt wird, da die Referenz übergeben und der Wert "a" in der Referenz aktualisiert wird.

Beispiel mit Primitiv:

var f1 = function(a){
    a = 2;
}
var f2 = function(){
    var a = 1;
    f1(a);
    console.log(a);
}

Der Aufruf von f2 führt dazu, dass der Wert "a" als 1 ausgedruckt wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X