第二次调用常规方法时,对象值会被覆盖

时间:2017-06-13 11:27:57

标签: javascript angularjs

这有点奇怪。我确信我错过了编程的一些基本概念,但不确定是什么。因为到现在为止我从未遇到过这个问题。

让我通过编程来解释我的问题:

var result = {abc: 10, cde: 20, efg: 30};
var final_result = {};
var customFunction1 = function(results){
  console.log(results);
  return results; // result= {abc: 10, cde: 20, efg: 30}
};
var customFunction2 = function(results){
 results.cde = 100;
 results.efg = 500;
 return results; // {abc: 10, cde: 100, efg: 500}
};
final_result.result1 = customFunction1(result);
final_result.result2 = customFunction2(result);
console.log(final_result);

在上面的程序中,我将结果作为参数传递给函数,并将其返回值存储在“final_result.result1”中。 但是当我用相同的参数调用不同的函数时,这会被覆盖。 我得到的输出是:

  

{ “RESULT1”:{ “ABC”:10, “CDE”:100, “EFG”:500}, “结果2”:{ “ABC”:10, “CDE”:100, “EFG”:500 }}

预期的o / p是:  { “RESULT1”:{ “ABC”:10, “CDE”:20, “EFG”:30}, “结果2”:{ “ABC”:10, “CDE”:100, “EFG”:500}} < / p>

为什么final_result.result1的值被result.result2覆盖。

JSBin http://jsbin.com/mepizecuka/edit?js,console
Plunkr http://plnkr.co/edit/BF0UNnacV9UeXtyk3stI?p=preview

任何人都可以在这里帮助我。

2 个答案:

答案 0 :(得分:0)

你没有将同一个物体传递给相同的物品,并在依赖它后改变它。让我用一个例子解释一下。

var obj = {a:100};
var holder = {};
function changeValues( object )
{
    object.a = 5;
}
console.log(JSON.stringify(obj));
holder.test = obj; // our object is same with holder.test now.
holder.test2 = obj;// our object is same with holder.test2 now.
// holder.test = holder.test2 now;

changeValues(holder.test);
console.log(JSON.stringify(obj));

如果您想传递和更改参考,那么您可以克隆它。

    var obj = {a:100};
    var holder = {};
    function changeValues( object )
    {
        object.a = 5;
    }
    console.log(JSON.stringify(obj));
    holder.test = jQuery.extend({}, obj); // our object is cloned now;
    holder.test2 = obj;// our object is same with holder.test2 now.
    // holder.test != holder.test2 now;

    changeValues(holder.test);
    console.log(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

现在你在holder.test中有不同的对象......

答案 1 :(得分:0)

我在这里看不到任何代码问题。

这是JavaScript的工作方式(或者大多数语言工作,参数传递参数时)。

您的初始result是一个对象,它是JavaScript中的引用类型。这意味着相同的(单个)引用将传递给您的所有函数。

让我们假设您的result对象在内存中的某处被分配了引用A。 因此,当您将result传递给第一个函数时,它将传递给引用A。在这里,您不会更改它,返回的输出仍指向A,值也相同。您已将同一参考A分配给final_results.result1

此后,您将结果传递给function2,这意味着现在将相同的引用A传递给function2。这次你改变了几个值。这意味着在引用上更改了值,并且将在使用引用的任何位置更改这些值。接下来,您将输出分配给final_results.result2

现在你有一个final_result obj,它包含2个属性,基本上这2个属性引用相同的内存引用A。这就是你在第二次函数调用后改变的原因。

简而言之:JS中的对象和数组也通过引用传递,而其他类型如numberstring则按值传递。因此,如果result最初是原始的(比如var result = 20之类的数字),则不会出现同样的问题。

关于处理此问题的解决方案,@ Burak已经向您展示了一种方法。还有其他人。也许你应该找到它们。