424 Stimmen

JavaScript durch Verweis vs. durch Wert

Ich bin auf der Suche nach einigen guten umfassenden Lesestoff auf, wenn JavaScript übergibt etwas durch Wert und wenn durch Verweis und wenn die Änderung einer übergebenen Element wirkt sich auf den Wert außerhalb einer Funktion und wenn nicht. Ich interessiere mich auch dafür, wann die Zuweisung an eine andere Variable per Referenz und wann per Wert erfolgt und ob dies anderen Regeln folgt als die Übergabe als Funktionsparameter.

Ich habe viel gesucht und viele konkrete Beispiele gefunden (viele davon hier auf SO), aus denen ich Teile der wirklichen Regeln zusammensetzen kann, aber ich habe noch kein einziges, gut geschriebenes Dokument gefunden, in dem alles beschrieben ist.

Gibt es außerdem Möglichkeiten, in der Sprache zu steuern, ob etwas als Referenz oder als Wert übergeben wird?

Hier sind einige der Fragen, die ich verstehen möchte. Das sind nur Beispiele - ich möchte eigentlich die Regeln verstehen, nach denen die Sprache funktioniert, nicht nur die Antworten auf bestimmte Beispiele. Aber hier sind einige Beispiele:

function f(a,b,c) {
   a = 3;
   b.push("foo");
   c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);

Wann werden die Inhalte von x, y und z außerhalb des Geltungsbereichs von f für alle verschiedenen Typen geändert?

function f() {
    var a = ["1", "2", "3"];
    var b = a[1];
    a[1] = "4";
    // what is the value of b now for all possible data types that the array in "a" might hold?
}

function f() {
    var a = [{yellow: "blue"}, {red: "cyan"}, {green: "magenta"}];
    var b = a[1];
    a[1].red = "tan";
    // what is the value of b now and why?
    b.red = "black";
    // did the value of a[1].red change when I assigned to b.red?
}

Wenn ich eine völlig unabhängige Kopie eines Objekts erstellen möchte (ohne jegliche Verweise), was ist der beste Weg, um das zu tun?

724voto

nrabinowitz Punkte 54138

Meines Erachtens ist das eigentlich sehr einfach:

  • Javascript ist immer Wertübergabe, aber wenn sich eine Variable auf ein Objekt bezieht (einschließlich Arrays), ist der "Wert" ein Verweis auf das Objekt.
  • Ändern des Wertes einer Variablen nunca das zugrundeliegende Primitiv oder Objekt ändert, verweist sie die Variable lediglich auf ein neues Primitiv oder Objekt.
  • Allerdings ist die Änderung einer Eigenschaft eines Objekts, auf das eine Variable verweist, ändert das zugrunde liegende Objekt.

Um also einige Ihrer Beispiele durchzuarbeiten:

function f(a,b,c) {
    // Argument a is re-assigned to a new value.
    // The object or primitive referenced by the original a is unchanged.
    a = 3;
    // Calling b.push changes its properties - it adds
    // a new property b[b.length] with the value "foo".
    // So the object referenced by b has been changed.
    b.push("foo");
    // The "first" property of argument c has been changed.
    // So the object referenced by c has been changed (unless c is a primitive)
    c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);
console.log(x, y, z.first); // 4, ["eeny", "miny", "mo", "foo"], false

Beispiel 2:

var a = ["1", "2", {foo:"bar"}];
var b = a[1]; // b is now "2";
var c = a[2]; // c now references {foo:"bar"}
a[1] = "4";   // a is now ["1", "4", {foo:"bar"}]; b still has the value
              // it had at the time of assignment
a[2] = "5";   // a is now ["1", "4", "5"]; c still has the value
              // it had at the time of assignment, i.e. a reference to
              // the object {foo:"bar"}
console.log(b, c.foo); // "2" "bar"

62voto

nnnnnn Punkte 142888

Javascript immer geht nach Wert. Wenn Sie jedoch ein Objekt an eine Funktion übergeben, ist der "Wert" in Wirklichkeit ein Verweis auf dieses Objekt, so dass die Funktion die Eigenschaften des Objekts ändern kann aber nicht dazu führen, dass die Variable außerhalb der Funktion auf ein anderes Objekt zeigt .

Ein Beispiel:

function changeParam(x, y, z) {
  x = 3;
  y = "new string";
  z["key2"] = "new";
  z["key3"] = "newer";

  z = {"new" : "object"};
}

var a = 1,
    b = "something",
    c = {"key1" : "whatever", "key2" : "original value"};

changeParam(a, b, c);

// at this point a is still 1
// b is still "something"
// c still points to the same object but its properties have been updated
// so it is now {"key1" : "whatever", "key2" : "new", "key3" : "newer"}
// c definitely doesn't point to the new object created as the last line
// of the function with z = ...

29voto

Ja, Javascript übergibt immer nach Wert, aber in einem Array oder Objekt ist der Wert ein Verweis darauf, so dass Sie den Inhalt "ändern" können.

Aber ich glaube, Sie haben es bereits auf SO gelesen; aquí Sie haben die gewünschte Dokumentation:

http://snook.ca/archives/javascript/javascript_pass

19voto

Mukund Kumar Punkte 17476
  1. Primitive Variablen wie Zeichenketten und Zahlen werden immer als Durchgang weitergegeben. nach Wert übergeben.
  2. Array und Object wird als pass by reference oder pass by value übergeben, basierend auf diesen beiden Bedingungen.

    • wenn Sie den Wert dieses Objekts oder Arrays mit einem neuen Objekt oder Array ändern, wird es von Value übergeben.

      object1 = {item: "car"}; array1=[1,2,3];

    Hier weisen Sie ein neues Objekt oder Array dem alten zu. Sie ändern nicht den Wert der Eigenschaft des alten Objekts. Es handelt sich also um eine Übergabe nach Wert.

    • wenn Sie einen Eigenschaftswert eines Objekts oder Arrays ändern, wird dieser durch eine Referenz übergeben.

      object1.item= "car"; array1[0]=9;

    Hier ändern Sie einen Eigenschaftswert des alten Objekts. Sie weisen dem alten Objekt kein neues Objekt oder Array zu, also ist es eine Referenzübergabe.

Code

    function passVar(object1, object2, number1) {

        object1.key1= "laptop";
        object2 = {
            key2: "computer"
        };
        number1 = number1 + 1;
    }

    var object1 = {
        key1: "car"
    };
    var object2 = {
        key2: "bike"
    };
    var number1 = 10;

    passVar(object1, object2, number1);
    console.log(object1.key1);
    console.log(object2.key2);
    console.log(number1);

Output: -
    laptop
    bike
    10

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