预期成绩

我编写了一个函数,以获取简单的对象文字,并对其重新格式化,如本例所示:

var original = { a: 1, b: true, c: "a string" }

// run through function ...

var result = {
  a: { type: "int", val: 1 },
  b: { type: "bit", val: 1 },
  c: { type: "varchar(250)", val: "a string" }
}


当前解决方案

该函数起作用,使用for ... in循环遍历原始对象并基于原始数据构建新对象。

function change (data) {

  function loop (d) {

    var orig = d;
    var end = d;

    for (var key in orig) {

      var property = {
        type: "test",
        val: orig[key]
      };

      end[key] = property;
    }

    return end;
  }

  // create object using loop & return
  var p = loop(data);
  return p;

}


实际结果

但是,此功能还改变了传入的原始对象,我似乎无法弄清楚原因。

var original = { a: 1, b: true, c: "a string" }

// run through function ...
var result = change(original);

console.log(result);    // =>  {
                        //        a: { type: "int", val: 1 },
                        //        b: { type: "bit", val: 1 },
                        //        c: { type: "varchar(250)", val: "a string" }
                        //      }

console.log(original);  // =>  {
                        //        a: { type: "int", val: 1 },
                        //        b: { type: "bit", val: 1 },
                        //        c: { type: "varchar(250)", val: "a string" }
                        //      }
                        // instead of expected:
                        //      { a:1, b:true, c:"a string" }


我猜想这与我对javascript范围的不完全了解有关,可能与原型继承有关(我肯定需要了解更多信息),但是在这一点上,我不确定从哪里真正开始了解这里发生了什么。当我将其与我对JavaScript的副作用产生的简单理解进行比较时,我会感到非常困惑:

var a = 1;
var b = a;
console.log(a) // => 1
console.log(b) // => 1

b = 2
console.log(a) // => 1
console.log(b) // => 2


该功能按原样运行,并且在我的程序其余部分中正在做我需要做的事情,但是这个问题确实让我感到困扰,因为我不了解这里发生了什么。

最佳答案

在Javascript中,当您决定在函数中将对象作为参数传递时,该对象将作为对原始对象的引用,并且也会对其进行突变。

如果您像只读一样处理它,它将作为常规参数(通过值传递)

对于平坦的对象(不包含嵌套对象),可以使用Object.assign(具有可用polyfill的Es6功能)

let obj1 = { a: 1};
let obj2 = Object.assign({}, obj1);


对于更复杂的对象,我建议您使用一些库方法,例如lodash的_.cloneDeep

// you have to include lodash.js in your page
let obj1 = { a: 1};
let obj2 = _.cloneDeep(obj1);


或jQuery的$.extend

// you have to include jquery.js in your page
let obj1 = { a: 1};
let obj2 = $.extend(true, {}, obj1);

关于javascript - 影响新对象的一面正在更改原始对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38603734/

10-11 23:04
查看更多