简体   繁体   中英

Can one set multiple properties inside an object literal to the same value?

For example, can I do this?:

{ 
   a: b: c: d: 1,
   e: 2,
   geh: function() { alert("Hi!") }
}

EDIT: Is there some way I can avoid doing this?:

{ 
   a: 1,
   b: 1,
   c: 1,
   d: 1,
   e: 2,
   geh: function() { alert("Hi!") }
}

An update to this (in terms of the latest JavaScript abilities) avoiding unwanted defined vars:

{
  let v;
  var obj = {
     "a": (v = 'some value'),
     "b": v,
     "c": v
  };
}

This will mean v won't be defined outside the block, but obj will be.

Original answer

Another way of doing the same thing is:

var v;
var obj = {
     "a": (v = 'some value'),
     "b": v,
     "c": v
};

You could set a line of equality between various properties:

var foo = {};
foo.a = foo.b = foo.c = "Hello";

Or you could just create a method that does the mass-assignment for you:

var foo = {
    setValue: function( props, value ) {
        while ( props.length ) this[ props.pop() ] = value;
    }
}

foo.setValue( [ "a", "b", "c" ] , "Foo" );

You could try this. It's not the syntactic sugar you're looking for (eg. {a,b,c:1, d:2} ) but it's another way to do it, although all of these answers are pretty much fine.

(object,fields,value)=>Object.assign(object||{}, ...fields.map(f=>({[f]:value}) ))

Explanation:

(object,fields,value)=>

Takes an object (or falsey value if you want a new object, feel free to rearrange the argument order)

Object.assign(object||{},

Will return an object based on object and it will mutate the object. To disable this, simply add a first argument object literal like this Object.assign({}, object || {}, ...

...fields.map(f=>({[f]:value}) )

Will spread the array of fields mapped to objects as a list of extra arguments to Object.assign . ['a','b'].map(f=>({[f]:value}) ) will give [{a:value}, {b:value}] and f(...[{a:1},{b:1}]) is like f({a:1},{b:1}) . Object.assign does the rest :)

There's yet another approach: using a mapping function...

 // This will be standard! if (!Object.fromEntries) Object.fromEntries = entries => entries.reduce ((o, [key, value]) => ({ ...o, [key]: value }), {}) const setSameValue = (source, props, value) => ({ ...source, ...Object.fromEntries ( props.map (prop => [prop, value]) ) }) // The important part: do what you want with ease! const output = setSameValue ({}, ['1', '01'], 'string 1') const obj = { x: 1, y: 'hello' } const output2 = setSameValue (obj, ['1', '01'], 'string1') console.log ('output1:', output) console.log ('output2:', output2)

You could wrap in a closure too, if you didn't want multiple local vars. This syntax seems to be popular (but ugly):

var obj = (function() { var v='some value'; return { a:v, b:v, c:v }; })();

Use for of loop instead.

for (let [key, value] of Object.entries(object_name)) {
        object_name[key] = 0; // the value that you want to assign
      }

Or yet another way:

{...['a', 'b', 'c', 'd'].reduce((obj,prop)=>({...obj, [prop]: 1}), {}) }

It can be wrapped up pretty neatly by extending the Array prototype:

Array.prototype.ditto = function(v) { return this.reduce((o,p)=>({...o, [p]: v}), {}) }

So now it can be used like this:

{ 
    ...['a', 'b', 'c', 'd'].ditto(1),
    ...['e', 'f'].ditto(2)
    geh: function() { alert("Hi!") }
}

Explanation: the .reduce starts off with an empty object {} and for each element prop return an object which is whatever was in the object already ...obj plus a new property with our value 1: [prop]: 1 . Then expand these properties into the outer object with the ... at the start.

If you had tons of properties reduce wouldn't be the most efficient, but you could change it to:

Array.prototype.ditto = function(v) { let o = {}; this.forEach(p => o[p] = v); return o; }

More readable and more efficient but less cool??

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM