чтение / назначение ссылочных типов в JavaScript - PullRequest
0 голосов
/ 05 июля 2019

Мне нравится думать У меня есть понимание типов ссылок, но мне интересно, чего мне здесь не хватает, что происходит под капотом.

let o = {
   foo: 'bar'
};

console.log(o) // logs the object.

let p = o; // assigns reference to object

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

В обоих случаях мой ум читает это как ' читает значениео и '.Тем не менее, один будет регистрировать фактические данные, сохраненные в то время как другой вернет ссылку.Какой шаг я пропускаю, который отличает эти две строки?

  • - это let p = o;, как обычно работают, но console.log(o) вызывает некоторый тип неявного / вызова по умолчанию.

  • Или обратное, что o естественным образом вытянет реальный объект из кучи, но назначение по природе всегда будет назначать ссылку?

"когда x JavaScript будет z"

Может кто-нибудь объяснить, как это работает, так что я понимаю, почему именно это?

Ответы [ 2 ]

1 голос
/ 05 июля 2019

В вашем примере кода и 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. Он создает новую временную переменную, ограниченную этой функцией, и назначает копию указателя на этот объект, а затем делает эту именованную переменную параметра доступной в области действия функции. Затем функция может получить доступ к этому объекту через локальный указатель на него.

1 голос
/ 05 июля 2019

Если вы скопируете значение, то скопируете ссылку на объект.

Если вы сделаете с ним что-нибудь еще, то за ссылкой последует и объект будет работать с *.1005 *


Значение o является ссылкой на объект.

Если вы присваиваете o для p, то вы копируете эту ссылку, а p также является ссылкойк объекту.

Если вы обращаетесь к o.foo, вы переходите по ссылке на объект и делаете что-то со свойством foo.

Если вы передаете o вфункция, затем вы копируете ссылку на параметр в функции.Если эта функция затем обращается к paramater.foo, то она следует за ссылкой на объект и делает что-то со значением foo.

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