在JavaScript中从对象中复制某些属性的最有效方法是什么?

What is the most efficient way to copy some properties from an object in JavaScript?

本文关键字:有效 是什么 属性 方法 JavaScript 对象 复制      更新时间:2023-09-26

比如说,我有一个对象:

const user = {_id: 1234, firstName: 'John', lastName: 'Smith'}

我想创建另一个没有_id键的对象:

const newUser = {firstName: 'John', lastName: 'Smith'}

我正在使用这个:

const newUser = Object.assign({}, {firstName: user.firstName, lastName: user.lastName})

有更好的方法吗?

您可以通过解构:

来实现它

const user = { _id: 1234, firstName: 'John', lastName: 'Smith' };
const { _id, ...newUser } = user;
console.debug(newUser); 

然而,在撰写此回答时,扩展(...)语法仍处于ECMAScript提案阶段(阶段3),因此在实践中可能不会普遍可用。你可以把它和"翻译"一起使用。

Array#reduce方法做Object.keys方法。

const user = {
  _id: 1234,
  fistName: 'John',
  lastName: 'Smith'
};
var res = Object.keys(user).reduce(function(obj, k) {
  if (k != '_id') obj[k] = user[k];
  return obj;
}, {});
console.log(res);

您进行了两次浅拷贝:一次是对象文字,另一次是Object.assign。所以只用第一个:

const newUser = {firstName: user.firstName, lastName: user.lastName};

最有效的可能是常规循环

const user = {_id: 1234, fistName: 'John', lastName: 'Smith'};
let   obj  = {}, key;
for (key in user) {
  if ( key !== '_id' ) obj[key] = user[key];
}
console.log(obj)

遍历对象键,将想要的属性键放在一个数组中,并使用Array.prototype.includes()仅将这些复制到新对象中。

const account = {
  id: 123456,
  firstname: "John",
  lastname: "Doe",
  login: "john123",
  site_admin: false,
  blog: "https://opensource.dancingbear/",
  email: "john123@example.com",
  bio: "John ❤️ Open Source",
  created_at: "2001-01-01T01:30:18Z",
  updated_at: "2020-02-16T21:09:14Z"
};
function selectSomeProperties(account) {
return Object.keys(account).reduce(function(obj, k) {
    if (["id", "email", "created_at"].includes(k)) {
        obj[k] = account[k];
    }
    return obj;
  }, {});
}
const selectedProperties = selectSomeProperties(account);
console.log(JSON.stringify(selectedProperties))

结果:

{"id":123456,"email":"john123@example.com","created_at":"2001-01-01T01:30:18Z"}

这个小函数将选择复制或不复制的特定键。排除优先:

function copy(obj, include=[], exclude=[]) {
  return Object.keys(obj).reduce((target, k) => {
    if (exclude.length) {
      if (exclude.indexOf(k) < 0) target[k] = obj[k];
    } else if (include.indexOf(k) > -1) target[k] = obj[k];
    return target;
  }, {});
}
// let's test it
const user = {
  _id: 1234,
  firstName: 'John',
  lastName: 'Smith'
};
// both will return the same result but have different uses.
console.log(
  'include only firstName and lastName:'n', 
  copy(user, ['firstName', 'lastName'])
);
console.log(
  'exclude _id:'n',
  copy(user, null, ['_id'])
);