Почему использование push или любого метода массива изменяет исходный массив, а назначение его чему-то другому - нет? - PullRequest
3 голосов
/ 30 октября 2019

Я не понимаю, почему присвоение массива новому значению не влияет на новый массив. Я знаю, что «push» изменяет исходный массив, а также сращивание, а фильтр или срез - нет, это не мой вопрос. Мой вопрос заключается в том, почему назначение не делает. я просмотрел старые ответы на вопросы о том, что он передается по ссылке, но, опять же, если он передается по ссылке, то изменение его значения также должно влиять на ссылку.

const modify = (someArray) => {
    // modified my array
    someArray.push(1)
    // modified my original array
    someArray[0] = 'A'

    // didn't modify my array and I want to know why.
    someArray = ['whatever']
}
let myArray = ['a', 'b']
modify(myArray)
console.log(myArray) //  ["A", "b", 1]

Ответы [ 3 ]

3 голосов
/ 30 октября 2019

В Javascript (и Java или C #) все по умолчанию передается значением !

Важно знать, каково значение. Эта строка let myArray = ['a', 'b'] создает новый массив в памяти и помещает ссылку на него в myArray. Теперь значение myArray является ссылкой на память, в которой находится ['a', 'b'].

Когда вы передаете ее функции modify, значение, которое является ссылкой, является скопированным от myArray до someArray. Это означает, что someArray может обращаться к одному и тому же сегменту памяти того же массива, поэтому измените значения внутри этого массива, но вы не можете изменить значение myArray (которое является ссылкой на этот массив) с someArray.

1 голос
/ 30 октября 2019

Поскольку я много раз описывал это новичкам, я обнаружил, что лучше всего рассматривать объекты в Javascript как передаваемые и назначаемые в качестве указателя (как в случае работы указателей в C / C ++). Итак, когда вы делаете это:

let a = [1,2,3];
let b = a;

Теперь у вас есть две переменные, каждая из которых имеет указатель на один и тот же массив [1,2,3]. Я считаю, что лучше всего думать о массиве, существующем сам по себе, и теперь у вас есть две переменные, каждая из которых указывает на этот массив. Когда вы присваиваете b = a, он не создает копию данных, он просто указывает b на те же данные, на которые указывал a.

Если вы модифицируете этот массив с помощью чего-то вродеa.push(4) или присваивание типа a[0] = 9, тогда один и только один массив, на который указывают a и b, был изменен. Таким образом, при доступе к этому массиву из a или из b вы увидите изменение, поскольку обе переменные указывают на один и тот же объект физического массива.

Но, если вы переназначите какой-либо другой массив на b вот так:

b = [9,8,7];

Вы только что взяли новый массив и поместили указатель на него в b. Другая переменная a по-прежнему указывает на тот же исходный массив, к которому привык. Он никак не изменился.

Когда вы передаете массив в качестве аргумента, как вы делаете в своей функции modify(), аргумент функции в функции аналогичен переменной b вприведенный выше пример. Это просто еще одна переменная, которая указывает на тот же массив. Если вы измените сам массив, то обе переменные будут указывать на один и тот же измененный массив. Но если вы переназначите переменную аргумента, чтобы теперь указывать на какой-то другой массив, это повлияет только на эту переменную.

1 голос
/ 30 октября 2019

['a', 'b'] - это массив. myArray - это переменная, которая ссылается на этот массив. someArray - это переменная, локальная для функции modify, которая примет значение myArray (т. Е. ссылка на ваш массив; поэтому и myArray, и someArray ссылаются на один и тот же массив),Как вы заметили, someArray.push(1) и someArray[0] = 'A' оба изменяют массив, на который ссылается someArray. someArray = ["whatever"] изменит ссылку из someArray на новый массив ['whatever'], но myArray все еще ссылается на старый массив. В конце функции переменная someArray исчезает (а ['whatever'] забывается, так как к ней больше ничего не относится).

В JavaScript нет способа изменить ссылку на переменную, переданную вфункция (как, например, C ++ может);вы можете манипулировать только теми полученными ссылочными ориентирами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...