ответ довольно просто: потому, что ECMAScript является передача по значению и не проход по ссылке, и вашим код доказывает это. (Точнее, это передача по отдельности, которая является определенным видом передачи по значению.)
См. Is JavaScript a pass-by-reference or pass-by-value language? для получения дополнительной информации.
ECMAScript использует pass-by-value, или, точнее, частный случай pass-by-value, где переданное значение равно всегда указатель. Этот специальный случай также иногда называют совместным использованием вызовов, совместным использованием вызовов по вызову или позором.
Это то же соглашение, что и Java (для объектов), C# (по умолчанию для ссылочных типов), Smalltalk, Python, Ruby и более или менее каждый объектно-ориентированный язык, когда-либо созданный.
Примечания: некоторые типы (например) Number
с фактически передаваемыми непосредственно по значению и не с посредническим указателем. Однако, поскольку они неизменяемы, в этом случае не наблюдается наблюдаемой поведенческой разницы между передачей по значению и совместным использованием вызова по объекту, поэтому вы можете значительно упростить свою ментальную модель, просто обработав все как вызов по-умолчанию, объект совместного пользования. Просто интерпретируйте эти особые случаи как внутреннюю оптимизацию компилятора, о которой вам не нужно беспокоиться.
Вот простой пример, который вы можете запустить, чтобы определить аргумент прохождения конвенции о ECMAScript (или любой другой язык, после перевода его):
function isEcmascriptPassByValue(foo) {
foo.push('More precisely, it is call-by-object-sharing!');
foo = 'No, ECMAScript is pass-by-reference.';
return;
}
var bar = ['Yes, of course, ECMAScript *is* pass-by-value!'];
isEcmascriptPassByValue(bar);
console.log(bar);
// Yes, of course, ECMAScript *is* pass-by-value!,
// More precisely, it is call-by-object-sharing!
Если вы знакомы с C# , это очень хороший способ понять различия между передачей по значению и передачей по ссылке для типов значений и ссылочных типов, поскольку C# поддерживает все 4 комбинации: pass-by-value для типов значений («традиционный pass- по-значение "), пошаговые значения для ссылочных типов (совместное использование вызовов, вызов по объекту, обмен вызовами по-объектам, как в ECMAScript), пошаговые ссылки для ссылочных типов и пошаговые ссылки для типов значений.
(На самом деле, даже если вы не знаю C#, это не слишком трудно следовать.)
struct MutableCell
{
public string value;
}
class Program
{
static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux)
{
foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.";
foo = new string[] { "C# is not pass-by-reference." };
bar.value = "For value types, it is *not* call-by-sharing.";
bar = new MutableCell { value = "And also not pass-by-reference." };
baz = "It also supports pass-by-reference if explicitly requested.";
qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." };
}
static void Main(string[] args)
{
var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" };
var corge = new MutableCell { value = "For value types it is pure pass-by-value." };
var grault = "This string will vanish because of pass-by-reference.";
var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." };
IsCSharpPassByValue(quux, corge, ref grault, ref garply);
Console.WriteLine(quux[0]);
// More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.
Console.WriteLine(corge.value);
// For value types it is pure pass-by-value.
Console.WriteLine(grault);
// It also supports pass-by-reference if explicitly requested.
Console.WriteLine(garply.value);
// Pass-by-reference is supported for value types as well.
}
}
Этот ответ может помочь вам понять «пройти по ссылке» в JavaScript http://stackoverflow.com/a/7744623/1793653 – shree33