【问题标题】:Modify JS Object in Pure Way纯方式修改 JS 对象
【发布时间】:2018-11-14 18:31:01
【问题描述】:

我有一个转换 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);

该函数返回所需的newPerson 对象,但也修改了原来的myPerson 对象。我宁愿以纯粹的方式执行此操作,不会修改原始的 myPerson 对象。

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

【问题讨论】:

  • 你为什么创建capName只是为了立即删除它?
  • 也是一个错字,我的错!
  • 顺便说一句,功能不纯...

标签: javascript ecmascript-6 functional-programming ecmascript-5


【解决方案1】:

很容易解构:

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

我真的需要兼容 ES5

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

【讨论】:

  • 我可以很好地转换它。谢谢!
【解决方案2】:

只需使用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);

【讨论】:

  • Object.assign 也是 ES2015。
  • 他们明确要求 ES5。
  • @connexo 是的,我把它和 ES2015 混在一起了,但无论如何but I'd like to see the ES6 solution as well.,这也没错
【解决方案3】:

为了兼容 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);

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

【讨论】:

  • @JonasWilms 是的,但 OP 显示的对象没有自己的方法。尽管如此,还是值得一提。
  • @JonasWilms 添加了那条信息并添加了迭代 ownPropertiesperson 的版本。
  • 酷!我目前不担心保留任何方法。这里的两个解决方案都非常好。
【解决方案4】:

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

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 2021-05-03
    • 1970-01-01
    • 2013-10-20
    • 2012-09-18
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多