Передача по ссылке и передача по значению

Привет, разработчики! Сегодня мы обсудим одну из самых фундаментальных концепций в Javascript «Pass by Value» и «Pass by Reference». Эта концепция настолько важна, что даже этот вопрос часто всплывает на собеседовании. Почему? Понимание того, как это работает, поможет нам стать лучшим программистом, который сможет понять поток данных в приложении.

Прежде чем мы сможем погрузиться в объяснение. Мы должны знать, что в Javascript типы данных делятся на две категории: примитивные и непримитивные.

Вот список примитивных типов данных в Javascript:

  • string — массив символов

  • number — целое число, поплавок и т.д..

  • bigint — в случае, если вам нужны целые значения, большие, чем диапазон, поддерживаемый Number

  • boolean — истина или ложь

  • null — пустое значение

  • symbols — уникальное значение или часто используется как уникальный идентификатор, который не равен никакому другому значению

  • undefined — объявленная переменная, но значение еще не присвоено.

Между тем, все объекты, массивы и функции попадают под категорию непервичных типов данных.

Хорошо, мы разобрались. Давайте перейдем к объяснению!

Передача по ссылке

Давайте посмотрим на приведенный ниже код, чтобы понять, что такое передача по ссылке.

let john = {
  name: 'John Doe',
  gender: 'male',
  score: 95
};

let JohnDupe = john;
console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 95}
console.log(john); // {name: 'John Doe', gender: 'male', score: 95}
Вход в полноэкранный режим Выйти из полноэкранного режима

Итак, мы создали новую переменную JohnDupe и присвоили ей значение из John. Что произойдет, если мы изменим значение переменной JohnDupe?

johnDupe.score = 50;

console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 50}
console.log(john); // {name: 'John Doe', gender: 'male', score: 50}
Войдите в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что оценка значения John также изменилась! Что же произошло на самом деле? Когда мы создаем John (новый объект), мы сохраняем значение в памяти по некоторому адресу. И когда мы присваиваем значение из John в johnDupe, фактически вместо создания копии John, значение JohnDupe ссылается на значение (адрес) John в памяти.

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

let john = {
  name: 'John Doe',
  gender: 'male',
  score: 95
};

let anotherJohn = {...john}

anotherJohn.score = 50;

console.log(john); // {name: 'John Doe', gender: 'male', score: 95}
console.log(anotherJohn); // {name: 'John Doe', gender: 'male', score: 50}
Вход в полноэкранный режим Выход из полноэкранного режима

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

let person = {
  name: 'Nicola Tesla',
  gender: 'male',
};

let personDupe = person;

let anotherPerson = {
  name: 'Nicola Tesla',
  gender: 'male',
};

console.log(person === personDupe); // true
console.log(person === anotherPerson); // false
Вход в полноэкранный режим Выход из полноэкранного режима

В примере выше мы попытались сравнить equal person === personDupe, что приведет к выводу true, так как personDupe указывает на адрес из person. Однако когда мы попытались сравнить равные person === anotherPerson, будет выведено false, потому что они не являются одним и тем же объектом, даже если у них одинаковые свойства и значения.

Такое же поведение наблюдается и с Array.

let fruits = ['apple 🍎', 'strawberry 🍓', 'banana 🍌'];

let fruitsDupe = fruits;

let anotherFruits = ['apple 🍎', 'strawberry 🍓', 'banana 🍌'];

console.log(fruits === fruitsDupe); // true
console.log(fruits === anotherFruits); // false
Войти в полноэкранный режим Выход из полноэкранного режима

У меня есть аналогия, чтобы нам было легче понять «передачу по ссылке», если представить это как google sheet / google docs.

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

Джон, как президент класса, берет на себя инициативу и создает google docs, чтобы ученики могли легко сотрудничать. Затем Джон делится ссылкой с одноклассниками. Мэри — первая ученица, которая внесла изменения в документ и добавила несколько абзацев своей идеи о глобальном потеплении. Позже вечером Сьюзи открыла google docs и добавила свое мнение, затем Энди и так далее. Наконец, после того как все ученики закончили добавлять свое мнение, Джон передал документы google doc учителю. Все хорошо, и класс получил «А» за задание ✨.

Как видно из приведенного выше примера, независимо от того, сколько раз ученики вносили изменения в google docs, в конечном итоге они изменили только один файл (главный файл).

Пока все хорошо! Мы знаем, что такое передача по ссылке. ✨

Передача по значению

Если вы уже поняли, что такое передача по ссылке, то вы уже поняли, что такое передача по значению. Примитивные значения, такие как числа или строки, фактически создают копию.

const num = 10

function passByValue(val) {
  return val += 1
}


console.log('[passByValue]:', passByValue(num)) // [passByValue]: 11
console.log('[num]:', num) // [num:] 10
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше коде мы создаем переменную num со значением 10. Также мы создаем функцию passByValue, которая принимает значение в качестве параметра и прибавляет его к 1. Если мы попытаемся выполнить приведенный выше код, passByValue вернет 11, однако переменная num по-прежнему будет равна 10. Первоначальное значение num никак не изменится.


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

Оцените статью
devanswers.ru
Добавить комментарий