В javascript массив показывает поведение «передача по значению» вместо «передача по ссылке» - PullRequest
0 голосов
/ 30 сентября 2019

Я знаю, что массив, являющийся объектом в javascript, делает его непримитивными типами данных, что по умолчанию делает его передачей по ссылке. Теперь это верно в большинстве случаев, с которыми я сталкивался, однако код, которым я делюсь, демонстрирует странное поведение, которого я не понимаю, и это больше похоже на «тип передачи по значению».

var arr = ['a','b','c']
/*
function addArr(ar){
    ar.push('d')
    return ar
}

console.log(addArr(arr))  // ['a', 'b', 'c', 'd']
console.log(arr)          // ['a', 'b', 'c', 'd']
*/

//the above output is expected behavior for an Array object



function changeArr(ar){

    console.log(ar)   //1-// ['a', 'b', 'c']
    ar = ['12','11']
    console.log(ar)   //2-// ['12', '11']
    return ar
}

console.log(changeArr(arr)) //3-// ['12', '11']
console.log(arr)            //4-// ['a', 'b', 'c']

//now I expect the forth console output to be  ['12','11'] here because it is an object

Ответы [ 3 ]

0 голосов
/ 30 сентября 2019

Вы в основном повторно получаете объект, а не модифицируете исходный объект.

ar = ['12','11']

Вот почему Javascript переназначает новое значение.

0 голосов
/ 30 сентября 2019

Пожалуйста, смотрите комментарии.

let arr = [1, 2, 3, 4];

function changeArr(ar) {

  //console.log(ar)
  ar = ['12', '11'] // creating a new array ie creating a new space in heap putting these values there and storing its reference in ar or assigning it to the reference 
  //console.log(ar)
  return ar
}

function changeArr2(ar) {


  ar.push(55); // here we have changed the array  that is pointed by the reference stored in ar

  return ar
}

console.log(changeArr(arr))
console.log(changeArr2(arr));
console.log(arr) // now the original array contains 55 too

Для более четкой картины смотрите здесь - https://stackoverflow.com/a/57852144/7849549

0 голосов
/ 30 сентября 2019
function changeArr(ar){

    console.log(ar)
    ar = ['12','11'] // <- THIS LINE RIGHT HERE
    console.log(ar)
    return ar
}

Вы создаете новый массив, а не манипулируете старым. Каждый раз, когда вы вызываете эту функцию, вы создаете новый массив и возвращаете новый (если вы вызовете эту функцию 5 раз, вы получите 5 новых массивов). Тот, который вы передали в качестве входных данных, не имеет значения и остается без изменений.

EDIT Единственное отношение между новым массивом, который вы создаете, и тем, что вы передали в качестве ввода, заключается в том, что они используют один и тот жеимя переменной внутри замыкания, так что внутри этого замыкания вы больше не сможете одновременно обращаться и к входу, и к новому массиву. Но это другая тема ...

Может быть, это прояснит это:

var x = 'something that is not an array'
console.log(changeArr(x));
console.log(x);

И это, возможно, сделает это яснее всего:

var arr = [1,2,3,4];
console.log(changeArr());
console.log(arr);
...