Примитивные типы (число, строка и т. Д.) Передаются по значению, но объекты неизвестны, поскольку они могут быть оба переданы по значению (в случае, если мы считаем, что переменная, содержащая объект, на самом деле является ссылкой на объект ) и передается по ссылке (когда мы считаем, что переменная для объекта содержит сам объект).
Хотя в конце это не имеет большого значения, я хочу знать, как правильно представлять аргументы, передавая соглашения. Есть ли выдержка из спецификации JavaScript, которая определяет, какой должна быть семантика в отношении этого?
javascript
pass-by-reference
pass-by-value
Данаил Начев
источник
источник
var x=3, y=x; f(x); alert(y === x);
то функцияf()
может сделать отчет о предупреждении,false
а неtrue
. В JavaScript это невозможно, поэтому это не передача по ссылке. Хорошо, что можно передавать ссылки на изменяемые объекты, но это не то, что означает «передача по ссылке». Как я уже сказал, это позор, что терминология настолько запутанная.Ответы:
Это интересно в JavaScript. Рассмотрим этот пример:
Это производит вывод:
obj1
бы это вообще не было ссылкой, то изменениеobj1.item
не повлияло бы наobj1
внешние функции.num
было бы100
иobj2.item
будет читать"changed"
.Вместо этого, ситуация такова, что переданный элемент передается по значению. Но элемент, который передается по значению, сам по себе является ссылкой. Технически это называется совместным использованием вызовов .
На практике это означает, что если вы измените сам параметр (как с помощью
num
иobj2
), это не повлияет на элемент, который был передан в параметр. Но если вы измените ВНУТРЕННИЕ значения параметра, он будет распространяться обратно (как в случае сobj1
).источник
item
свойство объекта, на который ссылается obj1, вы меняете значение свойства элемента, которое изначально было установлено как «неизменное». Когда вы присваиваете obj2 значение {item: "ified "}, вы меняете ссылку на новый объект (который сразу выходит из области видимости при выходе из функции). Становится более очевидным, что происходит, если вы называете функцию params такими вещами, как numf, obj1f и obj2f. Затем вы видите, что параметры скрывали внешние имена переменных.ref
ключевого слова.) Обычно вам просто нужно, чтобы функция вернула новый объект, и выполните назначение в точке, где вы вызываете функцию. Например,foo = GetNewFoo();
вместоGetNewFoo(foo);
var obj1 = { item: 'unchanged' }; var obj2 = obj1; obj2.item = 'changed';
и наблюдать такой же эффект, как в вашем примере. Поэтому я лично отсылаю ответ Тима ГудманаОн всегда передается по значению, но для объектов значение переменной является ссылкой. Из-за этого, когда вы передаете объект и изменяете его члены , эти изменения сохраняются вне функции. Это выглядит как передача по ссылке. Но если вы на самом деле измените значение переменной объекта, вы увидите, что изменение не сохраняется, доказывая, что оно действительно передается по значению.
Пример:
Вывод:
источник
changeObject
, я изменил,x
чтобы содержать ссылку на новый объект.x = {member:"bar"};
эквивалентно ,x = new Object(); x.member = "bar";
что я говорю это также верно C #, кстати.ref
ключевое слово, вы можете передать ссылку по ссылке (вместо передачи по умолчанию ссылки по значению), а затем изменение, указывающее на anew Object()
, сохранится. ,Переменная не «держит» объект; он содержит ссылку. Вы можете присвоить эту ссылку другой переменной, и теперь обе ссылаются на один и тот же объект. Он всегда передается по значению (даже если это значение является ссылкой ...).
Нет никакого способа изменить значение, содержащееся в переменной, переданной в качестве параметра, что было бы возможно, если бы JavaScript поддерживал передачу по ссылке.
источник
Мои два цента ... Я так понимаю. (Не стесняйтесь поправлять меня, если я ошибаюсь)
Пришло время выбросить все, что вы знаете о передаче по значению / ссылке.
Потому что в JavaScript не имеет значения, передается ли он по значению, по ссылке или как угодно. Важна мутация против присвоения параметров, переданных в функцию.
Хорошо, позвольте мне сделать все возможное, чтобы объяснить, что я имею в виду. Допустим, у вас есть несколько объектов.
Что мы сделали, так это «присваивание» ... Мы присвоили 2 отдельных пустых объекта переменным «object1» и «object2».
Теперь предположим, что нам нравится object1 лучше ... Итак, мы «назначаем» новую переменную.
Затем, по какой-либо причине, мы решаем, что нам нравится объект 2 лучше. Итак, мы просто делаем небольшое переназначение.
Ничего не случилось с object1 или object2. Мы не изменили никаких данных вообще. Все, что мы сделали, это переназначили наш любимый объект. Важно знать, что object2 и FavoritesObject назначены одному и тому же объекту. Мы можем изменить этот объект с помощью любой из этих переменных.
Хорошо, теперь давайте посмотрим на примитивы как строки, например
Опять выбираем любимую.
Обе переменные favouriteString и string1 присвоены «Hello world». А что если мы захотим изменить нашу любимую строку ??? Что случится???
Э-э-э ... Что случилось? Мы не могли изменить string1, изменив favourString ... Почему ?? Потому что мы не изменили наш строковый объект . Все, что мы сделали, это «RE ASSIGN» переменную favourString для новой строки. Это по существу отключило его от string1. В предыдущем примере, когда мы переименовали наш объект, мы ничего не назначали. (Ну, не для самой переменной , но мы присвоили свойство name новой строке.) Вместо этого мы просто мутировали объект, который поддерживает связи между двумя переменными и базовыми объектами. (Даже если бы мы хотели изменить или мутировать строку объект сам, мы не могли бы, потому что строки на самом деле неизменяемы в JavaScript.)
Теперь о функциях и передаче параметров .... Когда вы вызываете функцию и передаете параметр, то, что вы, по сути, делаете, это «присваивание» новой переменной, и оно работает точно так же, как если бы вы просто присваивали, используя знак равенства (=).
Возьмите эти примеры.
Теперь то же самое, но с функцией
Хорошо, теперь давайте приведем несколько примеров использования объектов вместо ... во-первых, без функции.
Теперь то же самое, но с вызовом функции
Хорошо, если вы прочитали весь этот пост, возможно, теперь вы лучше понимаете, как вызовы функций работают в JavaScript. Неважно, передается ли что-то по ссылке или по значению ... Что важно, так это присвоение или мутация.
Каждый раз, когда вы передаете переменную в функцию, вы «присваиваете» имя переменной параметра, как если бы вы использовали знак равенства (=).
Всегда помните, что знак равенства (=) означает присваивание. Всегда помните, что передача параметра в функцию в JavaScript также означает присваивание. Они одинаковы, и эти две переменные связаны одинаково (то есть они не связаны, если только вы не считаете, что они назначены одному и тому же объекту).
Единственный раз, когда «изменение переменной» влияет на другую переменную, - это когда мутирует базовый объект (в этом случае вы изменяете не переменную, а сам объект).
Нет никакого смысла проводить различие между объектами и примитивами, потому что это работает точно так же, как если бы у вас не было функции, а просто использовали знак равенства для присвоения новой переменной.
Единственная ошибка, когда имя переменной, которую вы передаете в функцию, совпадает с именем параметра функции. Когда это происходит, вы должны обрабатывать параметр внутри функции, как если бы это была целая новая переменная, приватная для функции (потому что это так)
источник
foo(char *a){a="hello";}
ничего не делает, но если вы это сделаете,foo(char *a){a[0]='h';a[1]='i';a[2]=0;}
это будет изменено снаружи, потому чтоa
это область памяти, переданная по значению, которое ссылается на строку (массив символов). Передача структур (аналогично объектам js) по значению в C допускается, но не рекомендуется. JavaScript просто применяет эти лучшие практики и скрывает ненужные и, как правило, нежелательные излишества ... и, несомненно, облегчает чтение.source = { "id":"1"}; copy = source /*this is wrong*/; copy.id="2"
этого источника все еще {"id": "1"}?Учтите следующее:
Итак,
забудьте о «передаче по ссылке / значению», не зацикливайтесь на «передаче по ссылке / значению», потому что:Чтобы ответить на ваш вопрос: указатели пройдены.
Несколько заключительных комментариев:
источник
{'George', 1}
значений, но использую только одно из них одновременно, то как управляются остальные? И что происходит, когда я назначаю переменную значению другой переменной? Затем я указываю на указатель или указываю на правый операнд? Вvar myExistingVar = {"blah", 42}; var obj = myExistingVar;
результатеobj
указывает на{"blah", 42}
илиmyExistingVar
?1)
я запустил профиль памяти в инструментах разработчика браузера для функции цикла, такой как описанная вами, и увидел скачки в использовании памяти на протяжении всего цикла. Казалось бы, это указывает на то, что новые идентичные объекты действительно создаются на каждой итерации цикла. Когда шипы внезапно падают, сборщик мусора просто очищает группу от этих неиспользуемых объектов.2)
Что касается чего-то подобногоvar a = b
, javascript не предоставляет механизм для использования указателей, и поэтому переменная никогда не может указывать на указатель (как вы можете в C), хотя базовый движок javascript, несомненно, использует их. Так что ...var a = b
укажутa
«к pointee правого операнда»Объект вне функции передается в функцию путем предоставления ссылки на внешний объект.
Когда вы используете эту ссылку для манипулирования своим объектом, это влияет на внешний объект. Однако, если внутри функции вы решили указать ссылку на что-то еще, вы вообще не затронули объект снаружи, потому что все, что вы делали, это перенаправляли ссылку на что-то еще.
источник
Думайте об этом так: это всегда передается по значению. Однако значением объекта является не сам объект, а ссылка на этот объект.
Вот пример, передавая число (примитивный тип)
Повторение этого с объектом дает разные результаты:
Еще один пример:
источник
Очень подробное объяснение о копировании, передаче и сравнении по значению и по ссылке содержится в этой главе книги «JavaScript: Полное руководство» .
источник
JavaScript всегда передается по значению ; все имеет значение типа.
Объекты являются значениями, а функции-члены объектов сами являются значениями (помните, что функции являются первоклассными объектами в JavaScript). Кроме того, относительно концепции, что все в JavaScript является объектом ; это не верно. Строки, символы, числа, логические значения, значения NULL и неопределенные значения являются примитивами .
Иногда они могут использовать некоторые функции-члены и свойства, унаследованные от своих базовых прототипов, но это только для удобства. Это не значит, что они сами являются объектами. Попробуйте следующее для справки:
В обоих оповещениях вы найдете значение, которое не определено.
источник
x = "teste"; x.foo = 12;
и т. Д. То, что свойство не является постоянным, не означает, что оно не является объектом. Как говорит MDN: в JavaScript почти все является объектом. Все примитивные типы, кроме null и undefined, рассматриваются как объекты. Им могут быть назначены свойства (назначенные свойства некоторых типов не являются постоянными), и они имеют все характеристики объектов. ссылкаВ JavaScript тип значения определяет только то, будет ли это значение присваиваться значением-копией или ссылкой-копией .
Примитивные значения всегда присваиваются / передаются значением-копией :
null
undefined
ES6
Составные значения всегда присваиваются / передаются по ссылке-копии
Например
В приведенном выше фрагменте, поскольку он
2
является скалярным примитивом,a
содержит одну начальную копию этого значения иb
ему назначается другая копия значения. При измененииb
вы никоим образом не меняете значение вa
.Но оба
c
иd
являются отдельными ссылками на одно и то же общее значение[1,2,3]
, которое является составным значением. Важно отметить, что ни больше,c
ниd
больше не «владеют»[1,2,3]
значением - оба являются равными равноправными ссылками на значение. Таким образом, при использовании любой ссылки для modify (.push(4)
) самого фактического общегоarray
значения это влияет только на одно общее значение, и обе ссылки будут ссылаться на вновь измененное значение[1,2,3,4]
.Когда мы выполняем присваивание
b = [4,5,6]
, мы абсолютно ничего не делаем, чтобы повлиять на то, гдеa
еще находится ссылка ([1,2,3]
). Чтобы сделать это,b
должен быть указатель,a
а не ссылка наarray
- но такой возможности в JS не существует!Когда мы передаем аргумент
a
, он присваивает копиюa
ссылкиx
.x
иa
являются отдельными ссылками, указывающими на одно и то же[1,2,3]
значение. Теперь внутри функции мы можем использовать эту ссылку для изменения самого значения (push(4)
). Но когда мы делаем назначениеx = [4,5,6]
, это никоим образом не влияет на то, куда указывает исходная ссылкаa
- все еще указывает на (теперь измененный)[1,2,3,4]
значение.Чтобы эффективно передать составное значение (например, an
array
) по значению-копированию, вам необходимо вручную сделать его копию, чтобы переданная ссылка не указывала на оригинал. Например:Составное значение (объект, массив и т. Д.), Которое может быть передано по ссылке-копии
Здесь
obj
действует как оболочка для скалярного примитиваa
. Когда передаетсяfoo(..)
, копияobj
ссылки передается и устанавливается наwrapper
параметр. Теперь мы можем использоватьwrapper
ссылку для доступа к общему объекту и обновить его свойство. После завершения функцииobj.a
увидит обновленное значение42
.Источник
источник
ну, речь идет о «производительности» и «скорости» и в простом слове «управление памятью» в языке программирования.
в javascript мы можем поместить значения в два слоя: type1 -
objects
и type2 - все другие типы значений, такие какstring
&boolean
& etcесли вы представляете память в виде квадратов ниже, в каждом из которых может быть сохранено только одно значение type2:
каждое значение type2 (зеленый) - это один квадрат, а значение type1 (синий) - их группа :
Дело в том, что если вы хотите указать значение type2, адрес прост, но если вы хотите сделать то же самое для type1-value, это совсем не просто! :
и в более сложной истории:
так вот ссылки могут спасти нас:
в то время как зеленая стрелка здесь является типичной переменной, фиолетовая - объектной переменной, так как у зеленой стрелки (типичной переменной) есть только одна задача (и это указывает на типичное значение), нам не нужно отделять ее значение от это так, мы перемещаем зеленую стрелку со значением того, куда он идет и во всех назначениях, функциях и так далее ...
но мы не можем сделать то же самое с фиолетовой стрелкой, мы можем захотеть переместить ячейку «Джон» здесь или много других вещей ... поэтому фиолетовая стрелка будет придерживаться своего места, и только типичные стрелки, которые были назначены ей, будут двигаться ...
очень запутанная ситуация, когда вы не можете понять, как изменяются ссылочные переменные, давайте рассмотрим очень хороший пример:
источник
Это немного больше объяснения для передачи по значению и передачи по ссылке (JavaScript). В этой концепции они говорят о передаче переменной по ссылке и передаче переменной по ссылке.
Передача по значению (примитивный тип)
Передача по ссылке (объекты)
c
, и он указывает на некоторую память, скажем (0x012).d
указывается на то же местоположение (0x012).Особый случай, передача по ссылке (объекты)
источник
c
устанавливается копия ссылки на новый объект.В JavaScript при назначении объекта переменной значение, присвоенное переменной, является ссылкой на объект:
источник
Семантика!! Установка конкретных определений обязательно сделает некоторые ответы и комментарии несовместимыми, поскольку они не описывают одно и то же, даже если используют одни и те же слова и фразы, но крайне важно преодолеть путаницу (особенно для новых программистов).
Прежде всего, существует несколько уровней абстракции, которые, кажется, понимают не все. Новым программистам, которые выучили языки 4-го и 5-го поколений, может быть трудно сосредоточиться на концепциях, знакомых ассемблеру или программистам на C, не ориентированным на указатели на указатели на указатели. Передача по ссылке не просто означает возможность изменения ссылочного объекта с помощью переменной параметра функции.
Переменная : объединенная концепция символа, который ссылается на значение в определенном месте в памяти. Этот термин обычно слишком загружен, чтобы использовать его отдельно при обсуждении деталей.
Символ : текстовая строка, используемая для ссылки на переменную (т.е. имя переменной).
Значение : конкретные биты, хранящиеся в памяти и на которые ссылается символ переменной.
Расположение памяти : где хранится значение переменной. (Само местоположение представлено числом, отдельным от значения, хранящегося в этом месте.)
Параметр функции : Переменная, объявленная в определении функции, используется для ссылки на переменные, передаваемые в функцию.
Аргумент функции : переменная вне функции, которая передается функции вызывающей стороной.
Переменная объекта : переменная, базовое значение которой не является самим «объектом», скорее ее значение является указателем (значением ячейки памяти) на другое место в памяти, где хранятся фактические данные объекта. В большинстве языков более высокого поколения аспект «указатель» эффективно скрывается за счет автоматической разыменования в различных контекстах.
Примитивная переменная : переменная, значение которой является фактическим значением. Даже эта концепция может быть усложнена автобоксом и подобными объектам контекстами различных языков, но общие идеи состоят в том, что значение переменной является фактическим значением, представленным символом переменной, а не указателем на другое место в памяти.
Аргументы и параметры функций - это не одно и то же. Кроме того, значение переменной не является объектом переменной (как уже указывалось различными людьми, но, очевидно, игнорируется). Эти различия имеют решающее значение для правильного понимания.
Передача по значению или вызов по совместному использованию (для объектов): Значение аргумента функции копируется в другое место в памяти, на которое ссылается символ параметра функции (независимо от того, находится он в стеке или в куче). Другими словами, параметр функции получил копию значения переданного аргумента ... И (критическое) значение аргумента НИКОГДА НЕ ОБНОВЛЯЕТСЯ / ИЗМЕНЕНО / ИЗМЕНЕНО вызывающей функцией. Помните, что значение переменной объекта НЕ является самим объектом, скорее это указатель на объект, поэтому передача переменной объекта по значению копирует указатель на переменную параметра функции. Значение параметра функции указывает на точно такой же объект в памяти. Сами данные объекта могут быть изменены непосредственно через параметр функции, НО значение аргумента функции НИКОГДА НЕ ОБНОВЛЯЕТСЯ, поэтому оно будет продолжать указывать на же самоеобъект во время и даже после вызова функции (даже если данные его объекта были изменены или если параметру функции назначен другой объект в целом). Неверно утверждать, что аргумент функции был передан по ссылке только потому, что указанный объект является обновляемым через переменную параметра функции.
Вызов / передача по ссылке : значение аргумента функции может / будет обновляться напрямую с помощью соответствующего параметра функции. Если это помогает, параметр функции становится эффективным «псевдонимом» для аргумента - они фактически ссылаются на одно и то же значение в одной и той же ячейке памяти. Если аргумент функции является переменной объекта, возможность изменять данные объекта ничем не отличается от случая передачи по значению, поскольку параметр функции по-прежнему будет указывать на тот же объект, что и аргумент. Но в случае переменной объекта, если для параметра функции задан совершенно другой объект, то аргумент также будет указывать на другой объект - этого не происходит в случае передачи по значению.
JavaScript не передается по ссылке. Если вы внимательно прочитаете, вы поймете, что все противоположные мнения неправильно понимают, что подразумевается под передачей по значению, и они ошибочно заключают, что возможность обновления данных объекта с помощью параметра функции является синонимом «передачи по значению».
Клонирование / копирование объекта. Создается новый объект и копируются данные исходного объекта. Это может быть глубокая или мелкая копия, но дело в том, что создается новый объект. Создание копии объекта является отдельным понятием от передачи по значению. Некоторые языки различают объект класса и структуры (или тому подобное) и могут иметь разное поведение для передачи переменных разных типов. Но JavaScript не делает ничего подобного автоматически при передаче объектных переменных. Но отсутствие автоматического клонирования объектов не означает переход по ссылке.
источник
JavaScript передает примитивные типы по значению и типы объектов по ссылке
- Брайан Би - Какие языки программирования передаются по ссылке?
Обновить
Вот опровержение этого:
В JavaScript нет «передачи по ссылке».
источник
Мой простой способ понять это ...
При вызове функции вы передаете содержимое (ссылку или значение) переменных аргумента, а не сами переменные.
Внутри функции переменные параметров
inVar1
иinVar2
получают передаваемое содержимое.Получив
inVar2
ссылку на{ prop: 2 }
, вы можете изменить значение свойства объекта.источник
Передача аргументов функции в JavaScript аналогична передаче параметров по значению указателя в C:
источник
Для программирования языка юристов, я прошел через следующие разделы ECMAScript 5.1 (который легче читать , чем в последнем издании), и пойти так далеко , как просить его в списке рассылки ECMAScript.
TL; DR : все передается по значению, но свойства объектов являются ссылками, а определение объекта явно отсутствует в стандарте.
Построение списков аргументов
Раздел 11.2.4 «Списки аргументов» говорит следующее о создании списка аргументов, состоящего только из 1 аргумента:
Раздел также перечисляет случаи, когда список аргументов имеет 0 или> 1 аргументов.
Таким образом, все передаются по ссылке.
Доступ к свойствам объекта
Раздел 11.2.1 «Средства доступа к свойствам»
Таким образом, свойства Объектов всегда доступны в качестве ссылки.
По ссылке
В разделе 8.7 «Тип спецификации ссылки» описано, что ссылки не являются реальными типами в языке - они используются только для описания поведения операторов удаления, typeof и присваивания.
Определение понятия "объект"
В редакции 5.1 определено, что «Объект - это набор свойств». Следовательно, мы можем сделать вывод, что значением объекта является коллекция, но что касается значения коллекции, оно плохо определено в спецификации и требует некоторых усилий для понимания.
источник
Документы MDN объясняют это ясно, не будучи слишком многословным:
Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description
источник
На языке низкого уровня, если вы хотите передать переменную по ссылке, вы должны использовать специальный синтаксис при создании функции:
Это
&age
ссылка наmyAge
, но если вы хотите значение, вы должны преобразовать ссылку, используя*age
.Javascript - это язык высокого уровня, который делает это преобразование для вас. Таким образом, хотя объекты передаются по ссылке, язык преобразует параметр ссылки в значение. Вам не нужно использовать
&
в определении функции передачу ее по ссылке*
, а также в теле функции, чтобы преобразовать ссылку в значение, JS сделает это за вас.Вот почему, когда вы пытаетесь изменить объект внутри функции, заменяя его значение (то есть
age = {value:5}
), изменение не сохраняется, но если вы изменяете его свойства (то естьage.value = 5
), это происходит.Учить больше
источник
Я прочитал эти ответы несколько раз, но ДЕЙСТВИТЕЛЬНО не получил его, пока не узнал о техническом определении «Звонок через обмен», как его назвала Барбара Лисков.
То есть ссылки на параметры могут быть изменены, если вы зайдете и получите доступ к самому значению параметра. С другой стороны, присвоение параметра исчезнет после оценки и будет недоступно для вызывающей функции.
источник
В основном самый простой способ
источник
JSON.parse( JSON.stringify( obj ) )
это ужасный способ глубоко клонировать объекты. Это не только медленно, но и может привести к потере данных.Я нашел способ продлить из библиотеки Underscore.js очень полезно , когда я хочу передать в объект в качестве параметра , который может быть либо изменены или заменены полностью.
источник
Самое краткое объяснение, которое я нашел, было в руководстве по стилю AirBNB :
Примитивы : когда вы обращаетесь к примитивному типу, вы работаете непосредственно с его значением
Например:
Сложный : при доступе к сложному типу вы работаете со ссылкой на его значение
Например:
Т.е. эффективно примитивные типы передаются по значению, а сложные типы передаются по ссылке.
источник
Я бы сказал, что это мимоходом -
Рассмотрим аргументы, а переменные объекты - это объекты, созданные во время контекста выполнения, созданного в начале вызова функции, а ваши фактические значение / ссылка, переданные в функцию, просто сохраняются в этих аргументах + переменных объектах.
Проще говоря, для примитивных типов значения копируются в начале вызова функции, для типа объекта ссылка копируется.
источник
Там какая - то дискуссия по поводу использования термина «передать по ссылке» в JavaScript здесь , но ответить на ваш вопрос:
(Из статьи, упомянутой выше.)
источник
Простой способ определить, является ли что-то «передачей по ссылке», заключается в том, можете ли вы написать функцию «подкачки». Например, в C вы можете сделать:
Если вы не можете сделать эквивалент этого в JavaScript, это не «передача по ссылке».
источник
Массив и Объект передаются как передача по ссылке или передача по значению на основе этих двух условий.
если вы меняете значение этого объекта или массива с помощью нового объекта или массива, то оно передается по значению.
object1 = {item: "car"}; array1=[1,2,3];
здесь вы присваиваете новый объект или массив старому. Вы не меняете значение свойства старого объекта. Так что оно передается по значению.
если вы изменяете значение свойства объекта или массива, оно передается по ссылке.
object1.key1= "car"; array1[0]=9;
здесь вы изменяете значение свойства старого объекта. Вы не назначаете новый объект или массив старому. поэтому он передается по ссылке.
Код
источник
источник
Простые значения внутри функций не будут изменять эти значения за пределами функции (они передаются по значению), тогда как сложные значения будут (они передаются по ссылке).
источник