JavaScript - 给对象字面量添加属性并返回

12

我有一个对象文字,我认为它是基本对象:

var obj = {
   key1   : 'value1',
   key2   : 'value2'
}

我想使用这个对象,并将其作为具有扩展名的参数传递给函数

myFunction( obj + { key3 : 'value3' } );

// param became:
{
   key1   : 'value1',
   key2   : 'value2',
   key3   : 'value3'
}
或者
myFunction( obj + { key2 : 'new value2' } );

// param became:
{
   key1   : 'value1',
   key2   : 'new value2'
}

+操作符不适用于此。我该如何做?是否有其他方法?

编辑:您是否想永久更改obj?- 不,我希望能够在下一次调用时重新使用它作为基础。

4个回答

23

使用ES2018或TypeScript 2.1,您可以使用对象展开语法

// properties on the right overwrite properties on the left

// Overwrite properties from obj
myFunction( { ...obj, key3: 'value3' } );

// Don't overwrite properties from obj
myFunction( { key3: 'value3', ...obj } );

使用ES2015,您可以使用Object.assign

// Object.assign(a, b, c, ..) - copy properties from b to a, then from c to a etc.

// Overwrite properties from obj
myFunction( Object.assign({}, obj, { key3: 'value3' }) );

// Don't overwrite properties from obj
myFunction( Object.assign({ key3: 'value3' }, obj) );

Demo

var obj = { key1: 'value1', key2: 'value2'}

console.log('-- Object Spread --');
console.log({ ...obj, key3: 'value3' });
console.log('overwrite');
console.log({ ...obj, key2: 'NEW2' });
console.log('no overwrite');
console.log({ key2: 'NEW2', ...obj });

console.log('-- Object Assign --');
console.log(Object.assign({ key3: 'value3' }, obj));
console.log('overwrite');
console.log(Object.assign({}, obj, { key2: 'NEW2' }));
console.log('no overwrite');
console.log(Object.assign({ key2: 'NEW2' }, obj));


console.log('-- Original Object unchanged --');
console.log(obj);


第二个ES2015示例可以缩短为myFunction( Object.assign({}, obj, { key3: 'value3' }) ); - Raphael Schweikert

9

如果你可以修改obj,那么在传递之前就进行更改:

var obj = { /* stuff */ };

obj.key3 = 'value3';
myFunction(obj);

您想永久更改 obj 吗?- 不,我希望能够在下一次调用时重复使用它作为基础。

好的,所以您需要复制 obj,并更改副本 - 或者在调用 myFunction 之前更改:

var obj = { /* stuff */ };
var extension = {key3: 'value3'};

myFunction($.extend({}, obj, extension));

或者将obj和"extension"传递给myFunction:

var obj = { /* stuff */ };
var extension = {key3: 'value3'};

myFunction(obj, extension);

myFunction来完成工作:

function myFunction(base, ext)
{
    if (typeof base === 'object' && typeof ext === 'object')
    {
        base = $.extend({}, base, ext);
    }

    // rest of the function logic here
}

如果您已经在使用jQuery,或者不介意使用它,那么$.extend()将成为您完成任务的最佳帮手。


你想永久改变 obj 吗?- 不,我希望能够在下一次调用时重复使用它作为基础。 - bensiu

0
你可以创建一个函数,以非破坏性的方式扩展对象(不是真正的“扩展”,只是从另一个对象创建一个新对象),例如:
var oldObj = {name: 'foo'};

function extendNonDestructive(src, newProps) {
  function F() {} F.prototype = src;
  var newObj = new F;
  for (var p in newProps) {
    if (newProps.hasOwnProperty(p)) {
      newObj[p] = newProps[p]
    }
  }
  return newObj
}

var newObj = extendNonDestructive(oldObj, {lastName: 'bar'}); // Doesn't touch oldObj

注意:你可能会对Object.create感兴趣,它比我代码中的小小的“function F() {}; F.prototype = src;”更加灵活,但它需要ES5+。


这就是 $.extend 的基本功能 - 只是没有 jQuery 的 ;-) - Matt Ball
而且我不知道他是否在使用jQuery。 - Alexander
关于jQuery,您的观点是完全有效的,不过$.extend()不必改变原始数据 - 只需将{}作为第一个参数传递即可。我在意识到这一点后编辑了我的答案。 - Matt Ball

0
如果您想要在一行中向现有对象添加属性并返回新对象,可以使用Object.fromEntries和Object.entries函数的组合:

console.log(
   Object.fromEntries(
    Object.entries({
      t:4,
      f:2
    })
    .concat(
      Object.entries({
            q:2,
            p:9
      })
    )
  )
);

 

This also works if you want to just modify a single property of an existing object, just, for the new object properties, add the object you want to replace, i.e.:

....concat(Object.entries({t:2}))...

只需修改原始对象的t属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接