Javascript by reference vs. by value [duplicate]

To pytanie ma już odpowiedź tutaj:

Szukam dobrego wyczerpującego materiału do czytania, kiedy Javascript przekazuje coś według wartości, a kiedy przez odniesienie i podczas modyfikowania przekazanego elementu wpływa na wartość poza funkcją, a kiedy nie. Ja też interesuje się przyporządkowaniem do innej zmiennej przez odniesienie vs. przez wartość i czy wynika to z innych reguł niż przekazywanie jako parametr funkcji.

Wykonałem wiele poszukiwań i znalazłem wiele konkretnych przykładów (wiele z nich tutaj na SO), od których mogę zacząć układać kawałki prawdziwych zasad, ale nie znalazłem jeszcze jednego, dobrze napisanego dokumentu, który opisuje to wszystko.

Również, czy istnieją sposoby w języku, aby kontrolować, czy coś jest przekazywane przez odniesienie czy wartość?

Oto niektóre z rodzajów pytań, które chcę zrozumieć. To są tylko przykłady - właściwie chcę zrozumieć zasady, którymi posługuje się język, a nie tylko odpowiedzi na konkretne przykłady. Ale oto kilka przykładów:

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

Kiedy zawartość X, y i z zmienia się poza zakresem f dla wszystkich różnych typów?

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

Jeśli chcę zrobić w pełni niezależną kopię obiektu (bez żadnych odniesień), co jest najlepsze poćwiczyć jak to zrobić?

Author: jfriend00, 2011-07-07

4 answers

Rozumiem, że jest to bardzo proste:

  • Javascript jest zawsze przekazywana przez wartość, ale gdy zmienna odnosi się do obiektu (łącznie z tablicami), "wartość" jest odniesieniem do obiektu.
  • zmiana wartości zmiennej nigdy nie zmienia podstawowego prymitywu lub obiektu, po prostu wskazuje zmienną na nowy prymityw lub obiekt.
  • jednak zmiana właściwości obiektu, do którego odnosi się zmienna, powoduje zmianę obiekt podstawowy.
Więc, do pracy przez niektóre z Twoich przykładów:
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

Przykład 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"
 551
Author: nrabinowitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-07 04:25:39

Javascript Zawsze przekazuje wartość. Jednak, jeśli przekazujesz obiekt funkcji, "wartość" jest w rzeczywistości odniesieniem do tego obiektu, więc funkcja może modyfikować właściwości tego obiektu , ale nie powodować, że zmienna poza funkcją wskazuje na inny obiekt.

Przykład:

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 = ...
 51
Author: nnnnnn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-07 04:19:08

Tak, Javascript zawsze przekazuje wartość, ale w tablicy lub obiekcie wartość jest odniesieniem do niej, więc możesz "zmienić" zawartość.

Ale, myślę, że już to przeczytałeś TAK; TUTAJ masz dokumentację, którą chcesz:

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

 24
Author: Edgar Villegas Alvarado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 02:25:13
  1. zmienna typu prymitywnego jak string, liczba jest zawsze przekazywana jako pass według wartości.
  2. Tablica i obiekt są przekazywane jako pass by reference lub pass by value na podstawie tych dwóch warunków.

    • Jeżeli zmieniasz wartość tego obiektu lub tablicy z nowym obiektem lub tablicą, to jest ona przekazywana przez wartość.

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

    Tutaj przypisujesz nowy obiekt lub tablicę do starego.nie zmieniasz wartości nieruchomości stare object.so przechodzi przez wartość.

    • Jeśli zmieniasz wartość właściwości obiektu lub tablicy, to jest ona przekazywana przez referencję.

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

    Tutaj zmieniasz wartość właściwości starego obiektu.nie przypisujesz nowego obiektu lub tablicy do starego one.so jest przekazywana przez odniesienie.

Kod

    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
 12
Author: Mukund Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 02:25:00