Является ли JavaScript языком передачи по ссылке или передачей по значению?

Примитивные типы (Number, String и т. Д.) Передаются по значению, но объекты неизвестны, поскольку они могут быть оба переданы по значению (в случае, если мы считаем, что переменная, содержащая объект, на самом деле является ссылкой на объект) и передается по ссылке (когда мы считаем, что переменная для объекта содержит сам объект).

Хотя в конце это не имеет большого значения, я хочу знать, как правильно представлять аргументы, передавая соглашения. Есть ли выдержка из спецификации JavaScript, которая определяет, какой должна быть семантика в отношении этого?

38 ответов

В некоторых случаях это может быть полезно для изменения anArg:

function alterMyArg(func) {
    // process some data
    // ...
    func(data);
}

alertMyArg(function(d) {anArg = d;});

В основном самый простой способ

// Copy JS object without reference
var first = {"a":"value1","b":"value2"};
var clone = JSON.parse( JSON.stringify( first ) ); 

var second = ["a","b","c"];
var clone = JSON.parse( JSON.stringify( second ) ); 

Я бы сказал, что это мимоходом -

Рассмотрим аргументы, а переменные объекты - это объекты, созданные во время контекста выполнения, созданного в начале вызова функции, а фактическое значение / ссылка, переданные в функцию, просто сохраняются в этих аргументах + переменных объектах.

Проще говоря, для примитивных типов значения копируются в начале вызова функции, для типа объекта - ссылка копируется.

  1. переменная типа примитива, такая как строка, число всегда передается как передаваемое значение.
  2. Массив и Объект передаются как передача по ссылке или передача по значению на основе этих двух условий.

    • если вы меняете значение этого объекта или массива с помощью нового объекта или массива, то оно передается по значению.

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

    здесь вы присваиваете новый объект или массив старому. Вы не меняете значение свойства старого объекта. Так что оно передается по значению.

    • если вы изменяете значение свойства объекта или массива, оно передается по ссылке.

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

    здесь вы изменяете значение свойства старого объекта. Вы не назначаете новый объект или массив старому объекту. Поэтому он передается по ссылке.

Код

    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
  1. Примитивы (Number, Boolean) передаются по значению.
    • Строки неизменны, поэтому для них это не имеет значения.
  2. Объекты передаются по ссылке (ссылка передается по значению)

Простой способ определить, является ли что-то "передачей по ссылке", состоит в том, можете ли вы написать функцию "подкачки". Например, в C вы можете сделать:

void swap(int *i, int *j)
{
    int t;
    t = *i;
    *i = *j;
    *j = t;
}

Если вы не можете сделать эквивалент этого в Javascript, это не "передача по ссылке".

Простые значения внутри функций не будут изменять эти значения вне функции (они передаются по значению), тогда как сложные значения будут (они передаются по ссылке).

function willNotChange(x) {

x = 1;

}

var x = 1000;

willNotChange(x);

document.write('After function call, x = ' + x + '<br>'); //still 1000

function willChange(y) {

y.num = 2;

}

var y = {num: 2000}; 

willChange(y);
document.write('After function call y.num = ' + y.num + '<br>'); //now 2, not 2000

Примитивы передаются по значению, а объекты передаются по ссылке. Это сильно отличается от других языков, таких как C, VB или Delphi. Я не могу сказать, как они точно обрабатывают объекты и примитивы, но я знаю о VB и Delphi, что он может (и должен) быть указан.

php делает то же самое, начиная с версии 5: все объекты передаются по ссылке, но все примитивы могут передаваться по ссылке, если перед ними стоит амперсанд (&). В противном случае примитивы передаются по значению.

Так что в javascript, если я передам объект X в функцию через параметр, это все равно будет X. Если вы изменяете данные внутри функции (или любой другой объект, но это не важно), это новое значение также доступно за пределами функция.

Другие вопросы по тегам