【问题标题】:JS: If variable gets object from a function, doas the variable stores the content of the object or a link to the object?JS:如果变量从函数中获取对象,变量是存储对象的内容还是对象的链接?
【发布时间】:2014-02-22 01:21:48
【问题描述】:

我是 Java Script 的新手,我不明白一个变量存储的是什么,如果它获取作为对象的函数的返回值。我担心的是,这样的变量不会存储值,而只是指向内存的链接,可能稍后会被覆盖。

我试过这个来找出答案:

此函数返回一个对象,其内容为:name="first" 或 name="second":

var returnObject = function (theSecond) {
    var obj = { name : "first" };
    if (theSecond) {
        obj.name = 'second';
    }
    return obj;
};

现在接收2个变量,函数返回什么:

var obj1 = returnObject(false); // obj3.name==first
var obj2 = returnObject(true);  // obj2.name==second

变量是存储函数中对象的副本,还是链接到函数中的对象? 如果它只是一个链接,则它们正在链接到已清除的内存,这可能会被意外覆盖。因此,我希望他们存储对象的副本。

obj3 只是指向 ojb1 的链接吗?

var obj3 = obj1;        // obj3 is a link to obj1?

看来,obj3 并没有存储 obj1 的副本,而只是一个指向 obj1 的链接,因为:

obj3.name = "third";    // obj3.name==third and immediately obj1.name==third

好的,现在显示的变量 obj1 与变量 obj3 相同,因为它是指向 obj3 的链接。

令人困惑:

obj1 = returnObject(false); // obj1.name==first BUT still obj3.name==third. WHY???

为什么链接现在断开了? obj3.name 仍然是“第三”,但 obj1.name 是“第一”!? obj3如何存储与obj1不同的值?

复制功能?

var copy = function (obj) { return obj; };

使用它:

obj2 = copy(obj1);      // obj2.name==first

obj2 现在是 obj1 的副本,还是指向 obj1 的链接?

obj2.name = "secondAgain";  

obj2.name 现在是 secondAgain 但立即 obj1.name 也是 secondAgain。看来,它不是复制功能。 obj2 只是指向 obj1 的链接。 :-(

现在我是一个困惑的 JavaScript 初学者。 :-((

标签:javascript对象复制函数链接返回值指针克隆赋值分配

更新:

我理解以下 2 个答案:

var retObj = function { return { name : "first" }; };
var objA = retObj();

... 具有相同的效果,如:

var objA = { name : "first" };

还有:

var copy = function (obj) { return obj; };
var objB = copy(objA);

... 具有相同的效果,如:

var objB = objA;

但是为什么:

...一个变量,即对另一个变量的引用,可以存储一个单独的对象吗?

var retObjX  = function () { return { name : "X"  }; };
var retObjX2 = function () { return { name : "X2" }; };
var objX = retObjX();   // objX=X
var objY = objX;        // Y refers X
objX = retObjX2();      // objX=X2 BUT! objY=X

我认为,变量 objY 不是对变量 objX 的引用,而是对 retObjX() 中的 objext 的引用,因为:objY 仍然显示 X 而不是 X2。

如果函数返回的对象不是常量字面量对象,而是动态构建的对象,那会怎样?引用变量会显示此函数上次构建的对象吗?

var retObjDyn = function () { return { rnd : Math.floor(Math.random() * 100) }; };
var objDynX = retObjDyn();  // 44
var objDynY = objDynX;      // 44
objDynX = retObjDyn();      // objDynX=78 BUT STILL: objDynY=44

objDynY 是对存储在 objDynX 中的对象的引用,它仍然显示该对象,即使 objDynX 显示不同的对象。

现在我认为, retObjDyn() 在每次调用时都会构建一个新对象。 但是这些对象是保存了,还是释放了内存用于其他事情?比 objDynY 可以意外更改其内容。

【问题讨论】:

  • @Givi:谢谢,你的链接是关于同一个问题。我仍然不确定,存储函数构建对象的内存是否受到保护并且不会被意外覆盖。

标签: javascript function object copy assign


【解决方案1】:

这似乎令人困惑,但实际上这是一个简单的概念。 JavaScript 中的对象是通过引用传递的,比如数组和对象;这是底线。

在你的第一个函数中,每次调用都会创建一个新对象:

var returnObject = function (theSecond) {
    var obj = { name : "first" }; // create a new object
    if (theSecond) {
        obj.name = 'second';
    }
    return obj; // return the new object
};

对象文字符号{} 创建一个新对象。

变量是否存储函数中对象的副本,或者 它们是否链接到函数中的对象?如果它只是一个链接,他们 正在链接到已清除的内存,这可能会被意外覆盖。 因此,我希望他们存储对象的副本。

变量obj1obj2 持有不同的对象。它们与函数无关。一旦函数返回对象,它就完成了,并且对象被分配给你的变量。没有内存泄漏。您可以检查它们是否是不同的对象:

obj1 === obj2 // false, not the same object

obj3 只是指向 ojb1 的链接吗?

var obj3 = obj1; 

是的,变量obj3与变量obj1拥有相同的对象,因此:

obj3 === obj1 // true, same object, just a reference

因此,根据这条规则,您的 copy 函数不是复制对象,而是获取一个对象并返回同一个对象。它不是副本。要复制一个对象,您必须创建一个新对象,并循环旧对象的所有属性,将它们分配给新对象,然后返回结果。一个简单的例子:

function copy(obj) {
  var newObj = {}; // a brand new object
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
      newObj[i] = obj[i]; // copy property
    }
  }
  return newObj;
}

【讨论】:

    【解决方案2】:

    变量不包含object,但它包含reference。如果将此变量分配给另一个变量,它们将共享相同的引用。

    据我所知:当您将对象(任何非原始对象)作为参数传递给函数时,将传递引用。这意味着您的复制功能实际上分配了引用。你的 returnObject 返回一个新的

    obj1 = returnObject(false) 将创建一个新对象(您在函数中对其进行实例化)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 2020-08-17
      • 2017-08-13
      • 2013-12-03
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      相关资源
      最近更新 更多