Возвращает ли метод фрагмента Javascript неглубокую копию?

В разработчике Mozilla, переведенном на корейский язык, говорится, что «метод среза» возвращает новый массив, скопированный неглубоко.

поэтому я проверил свой код.

var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

var t = animals.slice(2,4);
console.log(t);

t[0] = 'aaa';
console.log(t);
console.log(animals);

но, если метод среза возвращает неглубокий массив, массив животных должен быть изменен на ['муравей', 'бизон', 'ааа', 'утка', 'слон'].

Почему это мелкая копия?


person SeongUk Mun    schedule 10.12.2017    source источник
comment
Разве вы только что не процитировали документацию, в которой говорится, что это поверхностная копия и не изменяет оригинал? Я не понимаю вашего вопроса.   -  person Bergi    schedule 10.12.2017
comment
@Bergi Берги Я думаю, что документация читается как противоречие. Неглубокая копия имеет тот же адрес памяти, что и старая. Следовательно, любое изменение, внесенное в любой из них, изменяет атрибуты для обоих. Но в примере выше этого не происходит.   -  person sunwarri0r    schedule 11.03.2021
comment
@sunwarri0r Неглубокая копия имеет тот же адрес памяти, что и старая — нет, не так? Где ты это читаешь?   -  person Bergi    schedule 11.03.2021
comment
Я думаю, это понимание автора, поэтому он и задал этот вопрос. Также мой комментарий был неправильным, я надеюсь, что эта статья поможет и другим en.m.wikipedia.org /wiki/Object_copying#Shallow_copy   -  person sunwarri0r    schedule 11.03.2021


Ответы (4)


slice не изменяет исходный массив. Он возвращает неглубокую копию элементов исходного массива.

Элементы исходного массива копируются в возвращаемый массив следующим образом:

Для ссылок на объекты (а не для фактического объекта) срез копирует ссылки на объекты в новый массив. И исходный, и новый массив относятся к одному и тому же объекту. Если объект, на который делается ссылка, изменяется, эти изменения видны как в новом, так и в исходном массивах.

Для строк, чисел и логических значений (не объектов String, Number и Boolean) slice копирует значения в новый массив. Изменения строки, числа или логического значения в одном массиве не влияют на другой массив. Если в любой массив добавляется новый элемент, другой массив не затрагивается.(источник)

В вашем случае массив состоит из строк, которые на срезе будут возвращать новые строки, скопированные в массив, таким образом, это неглубокая копия. Чтобы этого избежать, используйте объектную форму массива.

person Naresh Kumar    schedule 10.12.2017

строки являются примитивными типами в JavaScript, поэтому вы получите новый массив с новыми строками внутри.

Ваш тестовый массив должен быть массивом объектов:

var animals = [{name: 'ant'}, {name: 'bison'}, {name: 'camel'}, {name: 'duck'}, {name: 'elephant'}];

var t = animals.slice(2,4);
console.log(t);

t[0].name = 'aaa';
console.log(t);
console.log(animals);

person klugjo    schedule 10.12.2017

Метод slice не изменяет исходный массив или строку. Он только вырезает часть исходной строки или массива и возвращает ее как копию. Чтобы лучше понять это, посмотрите это видео ниже: https://youtu.be/mUH8hPQfMbg [метод Slice легко для абсолютных новичков]

person Orisfina    schedule 07.09.2020

Может быть, вы ищете это. Попробуй это!

let animals = ['ant', 'bison', 'camel', [1, 2]];

let t = animals.slice();

t[0] = 'aaa';    // string (primitive datatype)
t[t.length-1][0] = 0;    // array (object)

console.log(t);
console.log(animals);

В случае мелкой копии-

  • Объекты будут отражать изменения в исходном месте, откуда они были поверхностно скопированы, потому что они хранятся как ссылки (по их адресу в куче).
  • Примитивные типы данных НЕ будут отражать изменения в исходном месте, поскольку они хранятся непосредственно в стеке вызовов (в контекстах выполнения).
person Rishabh Saxena    schedule 31.01.2021