Javascript赋值运算符的奇怪行为

Javascript assignment operator weird behaviour

本文关键字:赋值运算符 Javascript      更新时间:2023-09-26

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

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

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

你能帮我理解,为什么事件对象内竞争的属性值正在更新。我怎样才能防止这种情况而不更新事件对象?

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

你能帮我理解,为什么属性的值[喜欢]的 活动对象内的比赛正在更新

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

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

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

如果要确保旧值不应更新,则需要在分配时深层克隆对象

取代

var cmpt=event[0].competition;

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

您正在分配引用

    event[0].competition

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

在 JavaScript 中,对象总是通过引用传递。这意味着,当您将一个对象分配给另一个变量时,它仍然指向同一个对象。如果要有两个单独的对象,则必须克隆它。例如,您可以使用 lodash 库中_.clone()方法执行此操作:

var cmpt = _.clone(event[0].competition);

当你有一个对象,你像"复制"到一个新对象中一样,并更改新对象,旧对象就会更新。

这是因为您实际上并没有复制它,您只是对原始对象有另一个引用,因此您在"副本"上更改的内容都会反映在原始对象中......

这是因为

在 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

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

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
您可以使用

以下内容:

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) 

我怎样才能防止这种情况而不更新事件对象?

您可以使用第一个参数设置为 nullObject.create();在第二个参数value处迭代event[0].competition属性以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`