В вашем примере кода и o
, и p
являются указателями на один и тот же базовый объект Javascript.
Когда вы делаете это:
let o = {
foo: 'bar'
};
o
содержит указатель на объект Javascript. Важно не думать о o
как о самом объекте. Он содержит указатель на объект, и объект существует независимо от самой переменной. Я намеренно не называю это «ссылкой» на объект, потому что он не ведет себя полностью как ссылка. Если я назначу что-то еще для p
, это никак не изменит o
(таким образом, это не полная ссылка). Он ведет себя как указатель на языке, подобном C.
Когда вы назначаете такой указатель как в:
let p = o;
Javascript создает копию указателя из o
и помещает его в переменную p
. Каждая переменная o
и p
теперь содержит указатель на один и тот же объект. Если вы изменяете объект с помощью указателя o
или p
, есть только один объект, на который указывает каждый, так что вы увидите модификацию независимо от того, какую переменную вы используете для просмотра базового объекта.
// create an object and assign a pointer to that object to the variable o
let o = {
foo: 'bar'
};
// assign a pointer to the same object to the variable p
let p = o;
// modify the object pointed to by o
o.foo = 'hello';
// since both variables point to the same object, both see the modification
console.log(o.foo); // 'hello'
console.log(p.foo); // 'hello'
И o
, и p
указывают на один и тот же базовый объект. Таким образом, изменение этого объекта, независимо от того, какой указатель вы используете для его изменения, приведет к изменению базового объекта, и оба указателя будут по-прежнему указывать на один и тот же (теперь измененный) объект.
p
не является ссылкой на o
, потому что если я назначу что-то еще для p
, это никак не повлияет на o
.
let o = {
foo: 'bar'
};
let p = o;
o.foo = 'hello';
p = {foo: 'goodbye'}; // assign different object to p
console.log(o.foo); // o not affected by assignment of different pointer to p
Когда вы передаете этот указатель на функцию, как в:
console.log(o);
Он снова делает копию этого указателя (а не копию объекта) и передает его в качестве аргумента функции. Затем от функции, которую вы вызываете, зависит, что делать с аргументом, который вы передали. В этом случае console.log()
смотрит на тип аргумента, находит, что это указатель на объект, и затем решает использовать код, который у него есть, для вывода содержимого объекта. Именно внутренняя работа console.log()
анализирует тип аргумента и решает, что с ним делать.
Передача объекта в функцию в Javascript - это все равно, что присвоить этот объект другой переменной, и фактически это то, что делает Javascript. Он создает новую временную переменную, ограниченную этой функцией, и назначает копию указателя на этот объект, а затем делает эту именованную переменную параметра доступной в области действия функции. Затем функция может получить доступ к этому объекту через локальный указатель на него.