Недавно я столкнулся с интересным вопросом: «Значения в JS передаются по значению или ссылкой?»
Прежде чем анализировать эту проблему, мы должны понимать, что называется стоимостью, и что называется ссылкой. В информатике эта часть называется стратегией оценки. Он определяет, как проходят значения между переменными, между реальными параметрами и формальными параметрами при вызове функции.
Пройти по значению против Пройти через ссылку
Вызов по значению является наиболее часто используемой стратегией оценки: формальные параметры функции - это копии фактических параметров, передаваемых при вызове. Изменение значения формального параметра не повлияет на фактический параметр.
При прохождении с помощью ссылки (вызов по ссылке) формальные параметры функции получают неявную ссылку фактического параметра, а не копию. Это означает, что если значение параметра функции изменяется, фактический параметр также будет изменен. Оба указывают на одно и то же значение.
Прохождение ссылки затрудняет отслеживание функциональных вызовов, а иногда вызывает некоторые тонкие ошибки.
Проходите по значению, поскольку реплики клонируются каждый раз, производительность ниже для некоторых сложных типов. Оба метода прохождения ценностей имеют свои проблемы.
Давайте сначала рассмотрим пример C, чтобы понять разницу между прохождением по значению и ссылке:
Кода -копия выглядит следующим образом:
void modify (int p, int * q)
{
P = 27; // проходить по значению - копия фактического параметра A, только P изменяется
*Q = 27; // Q - это ссылка на B, и как Q, так и B изменяются
}
int main ()
{
int a = 1;
int b = 1;
Модифицировать (a, & b); // проход по значению, B проходит через ссылку,
// а не изменилась, B изменился
return (0);
}
Здесь мы можем увидеть:
a => Когда P передается по значению, изменение значения формального параметра P не влияет на фактический параметр a, p - просто копия a.
b => Q передается ссылкой. При изменении значения формального параметра Q он также влияет на значение фактического параметра b.
Изучите, как проходит значение JS
Основной тип JS передается по значению.
Кода -копия выглядит следующим образом:
var a = 1;
функция foo (x) {
x = 2;
}
foo (a);
console.log (a); // все еще 1, не затронуто назначением x = 2
Давайте посмотрим на объект:
Кода -копия выглядит следующим образом:
var obj = {x: 1};
функция foo (o) {
OX = 3;
}
foo (obj);
console.log (obj.x); // 3, модифицирован!
Объясните O и OBJ - это один и тот же объект, и O не является копией OBJ. Так что это не передается по цене. Но означает ли это, что объекты JS передаются ссылкой? Давайте посмотрим на следующие примеры:
Кода -копия выглядит следующим образом:
var obj = {x: 1};
функция foo (o) {
o = 100;
}
foo (obj);
console.log (obj.x); // все еще 1, OBJ не был изменен до 100.
Если он передается ссылкой, изменяя значение формального параметра o, он должен влиять на фактический параметр. Но изменение значения O здесь не влияет на OBJ. Следовательно, объекты в JS не передаются ссылкой. Итак, как проходить значение объекта в JS?
Пройти звонок, поделившись
Чтобы быть точным, основные типы в JS передаются значениями, а типы объектов передаются путем совместного использования (Call путем обмена, также вызываемые объектом и делится объектом). Впервые это было предложено Барбарой Лисков. На языке Glu 1974 года. Эта стратегия оценки используется в Python, Java, Ruby, JS и других языках.
Смысл этой стратегии заключается в том, что когда функция передает аргумент, функция принимает копию фактического эталона аргумента объекта (ни копия объекта, передаваемого значением, ни неявную ссылку, передаваемую ссылкой). Разница между ним и прохождением ссылки заключается в том, что назначение параметров функции в общем проходе не повлияет на значение фактического параметра. Как и в следующем примере, значение OBJ не может быть изменено путем изменения значения формального параметра o.
Кода -копия выглядит следующим образом:
var obj = {x: 1};
функция foo (o) {
o = 100;
}
foo (obj);
console.log (obj.x); // все еще 1, OBJ не был изменен до 100.
Однако, хотя ссылка является копией, ссылочный объект одинаков. Они разделяют один и тот же объект, поэтому изменение значения атрибута формального объекта параметра также повлияет на значение атрибута фактического параметра.
Кода -копия выглядит следующим образом:
var obj = {x: 1};
функция foo (o) {
OX = 3;
}
foo (obj);
console.log (obj.x); // 3, модифицирован!
Для типов объектов, поскольку объект изменен, изменение самого объекта повлияет на обмен ссылочной и эталонной копией объекта. Для основных типов, поскольку они оба неизменны, нет никакой разницы между прохождением путем совместного использования и прохождением по значению (вызов по значению), поэтому базовые типы JS соответствуют прохождению по значению и в соответствии с прохождением путем совместного использования.
Кода -копия выглядит следующим образом:
var a = 1; // 1 - номер типа, неизбежный var b = a; b = 6;
Согласно стратегии оценки, прошедшей общей, A и B являются двумя разными ссылками (B является справочной копией A), но ссылается на то же значение. Поскольку базовый тип № 1 здесь неизменен, нет никакой разницы между прохождением по стоимости и прохождением по обмену здесь.
Неизменные свойства основных типов
Основные типы неизменны, и только объекты изменяются. Например, числовые значения 100, логические значения являются истинными, ложными, и изменение этих значений (например, превращение 1 в 3, и превращение TRUE в 100) не имеет смысла. То, что легче неправильно понять, это строка в JS. Иногда мы стараемся «изменить» содержимое строки, но в JS любая операция «модифицировать», которая, кажется, является строковым значением, фактически создает новое строковое значение.
Кода -копия выглядит следующим образом:
var str = «abc»;
str [0]; // «а»
str [0] = "d";
Str; // все еще "ABC"; назначение недействительно. Нет возможности изменить содержание строки
Объект отличается, объект переменная.
Кода -копия выглядит следующим образом:
var obj = {x: 1};
obj.x = 100;
var o = obj;
OX = 1;
obj.x; // 1, модифицирован
o = true;
obj.x; // 1, не будет изменяться из -за O = true
Здесь определяется переменная OBJ, значение является объектом, и тогда значение свойства OBJ.X устанавливается на 100. Затем определите другую переменную O, и значение все еще остается этим объектом. В это время значения двух переменных OBJ и O указывают на один и тот же объект (разделение ссылки на один и тот же объект). Следовательно, изменение содержания объекта оказывает влияние как на OBJ, так и на O. Однако объект не передается ссылкой. Значение O изменяется с помощью O = true и не повлияет на OBJ.