JavaScript хранит ссылочные значения в памяти кучи и, таким образом, переменные хранятся в указателе / ​​адресе. Итак, если мы изменим исходную переменную, она также изменит назначенную:

var cols = ['red', 'blue', 'green']
var newCols = cols

cols.push('orange')

console.log(cols) 
// returns ["red", "blue", "green", "orange"]
console.log(newCols)
// returns ["red", "blue", "green", "orange"]

Однако, экспериментируя с ссылочными типами, я обнаружил, что когда я использую индексирование для присваивания и метода push, они действуют в другой логике, чего я не ожидал:

var cols = ['red', 'blue', 'green']
var newCols=cols[1]
cols[1] = "pink"
console.log(cols)
// returns > ["red", "pink", "green"]
console.log(newCols)
// returns > "blue"  WHY?

Но:

var cols = ['red', 'blue', 'green']
var newCols=cols
newCols[3] = 'orange'
cols.push('yellow')

console.log(cols)
// returns > ["red", "blue", "green", "orange", "yellow"]
console.log(newCols)
// returns > ["red", "blue", "green", "orange", "yellow"] WHY?

Итак, какова здесь логика («идея под капотом»), что в одном примере это влияет на оригинал, а в другом - нет?

1
Ulvi Enzo 24 Ноя 2020 в 04:15

1 ответ

Лучший ответ

Когда ты делаешь

var newCols=cols[1]

По сути, вы берете ссылку на значение, которое в настоящее время содержит cols[1], и newCols также указываете на него. Например, предположим, что cols[1], в настоящее время строка 'blue', находится в ячейке памяти # 5432. Тогда выполнение newCols=cols[1] имеет newCols также указывает на # 5432.

Массив cols также является массивом ссылок на ячейки памяти. Так что ['red', 'blue', 'green'] можно рассматривать как [#987, #5432, #123]. Переназначение одного из индикаторов помещает в это место новую ссылку. После cols[1] = "pink" вы можете думать о cols как о том, что теперь содержит [#987, #333, #123].

Исходный элемент в #5432 - 'pink' - не изменяется. newCols, который указывает на # 5432, по-прежнему указывает на 'pink'.

Когда ты делаешь

var newCols=cols

На контейнер всего массива указывает две переменные. Например, и cols, и newCols указывают на # 55555. Таким образом, изменение одного приведет к тому, что другой тоже изменится.

(«Место в памяти» - это полезная визуализация , но это не обязательно то, как все работает под капотом - это просто простой способ думать об этом)

1
CertainPerformance 24 Ноя 2020 в 01:20