Javascript赋值运算符奇怪的行为

时间:2016-05-06 14:04:04

标签: javascript variable-assignment assignment-operator

我正在处理一个事件小部件并发现了奇怪的行为,这可能是noob问题。

以下是我正在处理的代码块

var event={0:{competition:{like:false}}}
console.log(event[0].competition.like);   //returns false
var cmpt=event[0].competition;
cmpt.like=true;
console.log(event[0].competition.like) //returns true

你能帮我理解一下,为什么事件对象中竞争的属性[等]的价值会得到更新。 以及如何防止这种情况并且不更新事件对象?

我试着调查谷歌/所以但这些问题正在解决不同的问题。

8 个答案:

答案 0 :(得分:3)

  

你能帮助我理解,为什么属性[喜欢]的价值   事件对象内的竞争正在更新

您通过执行此分配复制了event[0].competitioncmpt的引用。

现在cmpt指向event[0].competition指向的同一对象。因此,如果更新该值,它将基本上在两个变量指向的同一对象中进行更改。

  

如何防止这种情况并且不更新事件对象?

如果您想确保不更新较旧的值,则需要在分配时深度克隆对象

替换

var cmpt=event[0].competition;

var cmpt=JSON.parse( JSON.stringify( event[0].competition ) );

答案 1 :(得分:1)

您正在分配对

的引用
    event[0].competition

变量cmpt然后修改它的值 - 无论你对原始实例做什么都会影响cmpt变量

答案 2 :(得分:1)

在JavaScript中,对象总是通过引用传递。这意味着当您将对象分配给另一个变量时,它仍然指向同一个对象。如果您想要两个单独的对象,则必须克隆它。您可以使用_.clone() method from lodash library

执行此操作
var cmpt = _.clone(event[0].competition);

答案 3 :(得分:1)

当你有一个对象时,你就像把它一样“复制”到一个新对象中,然后更改新对象就会更新旧对象。

这是因为你实际上没有复制它,你只是对原始对象有另一个引用,所以你在'副本'上所做的改变反映在原始对象中......

答案 4 :(得分:1)

这是因为在JavaScript中,当你将一个对象值分配给另一个变量时,你实际上正在为它赋值(它不会像原始值一样被复制)。

所以'cmpt'和'event [0] .competition'指的是同一个对象。

如果你需要克隆对象,它只包含原始值,数组和简单对象(没有函数),你可以使用'JSON.stringify'和'JSON.parse'。

var event={0:{competition:{like:false}}}
console.log(event[0].competition.like);       //returns false
var cmpt=JSON.parse(JSON.stringify(event[0].competition));
cmpt.like=true;
console.log(event[0].competition.like)
//returns false

答案 5 :(得分:1)

这就是为什么你只是"重命名"事件,你可以这样做。

var event={0:{competition:{like:false}}}
console.log(event[0].competition.like);   //returns false
var cmpt = {};
cmpt.like = event[0].competition.like;
cmpt.like = true;
console.log(event[0].competition.like) //returns false

答案 6 :(得分:1)

您可以使用以下内容:

var event={0:{competition:{like:false}}}
console.log(event[0].competition.like);   //returns false
var cmpt=jQuery.extend({}, event[0].competition);
cmpt.like=true;
console.log(event[0].competition.like) //returns false (changed) 

答案 7 :(得分:1)

  

如何防止这种情况并且不更新事件对象?

您可以使用Object.create()将第一个参数设置为null;将第event[0].competition个属性描述符的value属性迭代到Object.create(),将每个属性的值设置为null,返回属性为event[0].competition的新创建的对象设为null



var event = {
  0: {
    competition: {
      like: false
    }
  }
}

console.log(event[0].competition.like); //returns false

var cmpt = Object.create(null, {
  competition: {
    value: (function(obj) {
      var _obj = {};
      for (var prop in obj) {
        _obj[prop] = null
      };
      return _obj
    }(event[0].competition)),
    writable: true,
    enumerable: true,
    configurable: true
  }
});
cmpt.competition.like = true;
console.log(event[0].competition.like, cmpt.competition.like
           , event[0], cmpt) //`false, `true`