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