Nodejs 求助 关于 console

Nodejs 求助 关于 console

var obj={hello:1, world:2}; var fn = function(o){ var ref =o; console.log(ref); ref.good =“good”; }

fn(obj); fn(obj);

chrome 控制台输出为 :

Object {hello: 1, world: 2} Object {hello: 1, world: 2, good: “good”}

为什么两次输出不一样呢?

8 回复

当然可以。让我们详细分析一下你提供的代码,并解释为什么两次 console.log 的输出会有所不同。

示例代码

var obj = { hello: 1, world: 2 };
var fn = function (o) {
    var ref = o;
    console.log(ref);
    ref.good = "good";
};

fn(obj);
fn(obj);

输出结果

在 Chrome 控制台中,你会看到以下输出:

Object {hello: 1, world: 2}
Object {hello: 1, world: 2, good: "good"}

解释

  1. 第一次调用 fn(obj):

    • 当你调用 fn(obj) 时,参数 o 被赋值为对象 obj
    • var ref = o; 这行代码只是创建了一个对 obj 的引用(而不是复制)。
    • 因此,当执行 console.log(ref); 时,它打印的是当前 ref 的状态,即 { hello: 1, world: 2 }
  2. 修改 ref 对象:

    • 接下来,ref.good = "good"; 将属性 good 添加到 ref 对象上。
    • 由于 ref 是对原始对象 obj 的引用,所以这个操作实际上也修改了 obj
  3. 第二次调用 fn(obj):

    • 第二次调用 fn(obj) 时,同样的过程会发生。
    • 然而,由于第一次调用已经将 good 属性添加到了 obj 上,因此 ref 也会包含这个属性。
    • 所以,第二次 console.log(ref); 打印的已经是 { hello: 1, world: 2, good: "good" }

关键点

  • JavaScript 中的对象传递是按引用传递的。这意味着当你将一个对象传递给函数时,函数内部实际上得到的是该对象的一个引用。
  • 因此,在函数内部对对象所做的任何更改都会影响到原始对象。

示例代码修正

如果你想让两次输出一致,可以在函数内部创建一个新的对象副本,例如:

var obj = { hello: 1, world: 2 };
var fn = function (o) {
    var ref = Object.assign({}, o); // 创建对象的一个浅拷贝
    console.log(ref);
    ref.good = "good";
};

fn(obj);
fn(obj);

这样,每次调用 fn(obj) 时,ref 都是一个独立的对象,不会受到之前调用的影响。输出将会是:

{ hello: 1, world: 2 }
{ hello: 1, world: 2 }

希望这能帮助你理解问题的原因以及如何解决。


var obj={hello:1, world:2}; var fn = function(o){ var ref =o; console.log(ref); ref.good =“good”; }

fn(obj);//只调用一次

chrome 控制台输出为 :

Object {hello: 1, world: 2, good: “good”}

var obj={hello:1, world:2}; var fn = function(o){ var ref =o; console.log(ref); ref.good =“good”; }

fn(obj); ; //也是调用一次,再加个空语句

chrome 控制台输出为 :

Object {hello: 1, world: 2}

前面两次输出不一样是因为 fn 进行了赋值, 赋值前打印, 这个我想你能理解 后面两份代码, 我这边都是最后一个输出, 你要不要确定下?

在JavaScript中,对象是引用传值的。两次调用,但对象是同一个。

你的第二次实验结果值输出Object {hello: 1, world: 2},我测试的结果是这样。

引用传递

在你的代码中,ref 是对传入对象 o 的引用。当你第一次调用 fn(obj) 时,ref 指向 obj 的内存地址,因此你可以直接修改 obj 的属性。由于 obj 在内存中的地址没有改变,所以在第二次调用 fn(obj) 时,console.log 输出的对象已经包含了第一次调用时添加的 good 属性。

具体来说,refo 实际上指向的是同一个对象,因此对 ref 的任何修改都会反映到 o 上。这就是为什么你在第二次调用 fn(obj) 时看到的对象包含了 good 属性。

以下是你的代码加上一些注释:

var obj = { hello: 1, world: 2 };

var fn = function (o) {
    var ref = o; // ref 和 o 指向同一个对象
    console.log(ref); // 第一次输出:{ hello: 1, world: 2 }
    ref.good = "good"; // 修改对象
};

fn(obj);
fn(obj); // 第二次输出:{ hello: 1, world: 2, good: "good" }

总结:

  • 由于 refo 指向同一个对象,第一次调用 fn(obj) 会修改对象。
  • 第二次调用 fn(obj) 时,对象已经被修改,所以输出结果包含了 good 属性。
回到顶部