在JavaScript中读取/分配引用类型

时间:2019-07-05 07:51:29

标签: javascript ecmascript-6 computer-science

喜欢思考我对引用类型有理解,但是我想知道我在这里缺少什么,在幕后发生了什么。

let o = {
   foo: 'bar'
};

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

let p = o; // assigns reference to object

我已经看过1000遍了,然后继续思考,但这一次给了我一个意想不到的迷幻震撼

在两种情况下,我的头脑都将其读为“ 读取o和的值”。但是,一个将记录实际存储的数据,而另一个将返回引用。我错过了使这两行不同的哪一步?

  • let p = o;正常工作的方式,但是 console.log(o)导致某种类型的隐式/默认调用。

  • 或者相反,o自然会拉出实际对象 从堆中,但从本质上讲,分配将始终分配 参考?

“ x JavaScript将在何时出现”

有人可以解释一下它的工作原理,以便我确切知道为什么吗?

2 个答案:

答案 0 :(得分:1)

如果复制该值,则将对对象的引用复制。

如果您对其进行其他任何操作,则将遵循引用并使用该对象。


o的值是对对象的引用。

如果将o分配给p,则复制该引用,并且p也是对该对象的引用。

如果您访问o.foo,那么您将遵循对该对象的引用并使用其foo属性进行操作。

如果将o传递给函数,则将引用复制到函数中的参数。如果该函数随后访问paramater.foo,则它将遵循对该对象的引用,并对其执行值为foo的操作。

答案 1 :(得分:1)

在您的代码示例中,op都是指向同一基础Javascript对象的指针。

执行此操作时:

let o = {
   foo: 'bar'
};

o包含一个指向Javascript对象的指针。重要的是不要将o视为包含对象本身。它包含一个指向对象的指针,并且该对象独立于任一变量本身而存在。我故意不称其为对象的“引用”,因为它的行为不完全像引用。如果我为p分配了其他内容,则不会以任何方式更改o(因此它不是完整的参考)。它的行为就像使用C语言一样的指针。

当您分配如下指针时:

let p = o;

Javascript从o复制指针,并将其放入p变量中。现在,每个变量op都包含一个指向同一对象的指针。如果您通过op指针修改对象,则每个对象仅指向一个对象,因此无论您使用哪个变量查看基础对象,您都将看到修改。

// 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'

op都指向同一个基础对象。因此,修改该对象,无论您使用哪个指针对其进行修改,都将修改基础对象,并且两个指针仍将指向同一对象(现已修改)。

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所做的。它正在创建一个作用于该函数的新临时变量,并为该对象分配指针的副本,然后使该命名参数变量在该函数的作用域内可用。然后,该函数可以通过其对象的本地指针访问该对象。