纯方式修改JS对象

Modify JS Object in Pure Way

我有一个转换 JS 对象的函数。它从现有的 属性 派生出一个新的 属性,然后删除原来的 属性。本质上是这样的:

/** Derives "capName" property from "name" property, then deletes "name" */
function transform(person) {
  person["capName"] = person["name"].toUpperCase();
  delete person["name"];
  return person;
}

var myPerson = {
  name: "Joe",
  age: 20
};

var newPerson = transform(myPerson);

console.log(myPerson, newPerson);

函数returns得到了想要的newPerson对象,同时也修改了原来的myPerson对象。我宁愿以一种纯粹的方式来做这件事,不会修改原来的 myPerson 对象。

注意:我确实需要兼容ES5,但我也想看看ES6的解决方案。

只需使用 Object.assign 即可创建一个具有新引用的新对象

function transform(person) {
  var obj = Object.assign({}, person);
  obj["capName"] = obj["name"].toUpperCase();
  delete obj["name"];
  return obj;
}
        
var myPerson = {
  name: "Joe",
  age: 20
};

var newPerson = transform(myPerson);

console.log('newPerson:', newPerson);
console.log('myPerson:', myPerson);

解构非常简单:

 const transform = ({ name, ...rest }) => ({ capName: name.toUpperCase(), ...rest });

I really need to be ES5 compatible

使用BabelJS,它让你的生活变得更加轻松。

为了兼容 ES5,您可以使用 JSON.parse(JSON.stringify(person))。请注意,附加到 person 的方法会在途中丢失,因为它们无法正确 JSON.stringifyed。

/** Derives "capName" property from "name" property, then deletes "name" */
function transform(person) {
  var obj = JSON.parse(JSON.stringify(person));
  obj["capName"] = obj["name"].toUpperCase();
  delete obj["name"];
  return obj;
}

var myPerson = {
  name: "Joe",
  age: 20
};

var newPerson = transform(myPerson);

console.log(myPerson, newPerson);

如果你想保留方法,只需遍历对象键:

/** Derives "capName" property from "name" property, then deletes "name" */
function transform(person) {
  var obj = {};
  for (var key in person) {
    obj[key] = person[key];
  }
  obj["capName"] = obj["name"].toUpperCase();
  delete obj["name"];
  return obj;
}

var myPerson = {
  name: "Joe",
  age: 20
};

var newPerson = transform(myPerson);

console.log(myPerson, newPerson);

请注意,none 中提供的方法进行深度克隆。为此,我建议您使用类似 lodash 的 _.clone(obj, { deep: true });

您可以生成一个没有不需要的新对象和一个新的 属性。

function transform(person) {
    return Object
        .keys(person)
        .reduce(function (r, k) {
            if (k === 'name') {
                r.capName = person.name.toUpperCase();
            } else {
                r[k] = person[k];
            }
            return r;
        }, {});
}

var myPerson = { name: "Joe", age: 20 },
    newPerson = transform(myPerson);

console.log(myPerson);
console.log(newPerson);