Set default value of Javascript object attributes

Viewed 172471

Is there a way to set the default attribute of a Javascript object such that:

let emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue
19 Answers

The way I achieve this is with the object.assign function

const defaultProperties = { 'foo': 'bar', 'bar': 'foo' };
const overwriteProperties = { 'foo': 'foo' };
const newObj = Object.assign({}, defaultProperties, overwriteProperties);
console.log(defaultProperties);  // {"foo": "bar", "bar": "foo"}
console.log(overwriteProperties);  // { "foo": "foo" };
console.log(newObj);  // { "foo": "foo", "bar": "foo" }

This seems to me the most simple and readable way of doing so:

let options = {name:"James"}
const default_options = {name:"John", surname:"Doe"}

options = Object.assign({}, default_options, options)

Object.assign() reference

Simplest of all Solutions:

dict = {'first': 1,
        'second': 2,
        'third': 3}

Now,

dict['last'] || 'Excluded'

will return 'Excluded', which is the default value.

var obj = {
  a: 2,
  b: 4
};

console.log(obj);

--> {a: 2, b: 4}

function applyDefaults(obj) {
  obj.a ||= 10;
  obj.b ||= 10;
  obj.c ||= 10;
}

// do some magic
applyDefaults(obj);

console.log(obj);

--> {a: 2, b: 4, c: 10}

This works because

undefined || "1111111" --> "1111111"
"0000000" || "1111111" --> "0000000"

as null, undefined, NaN, 0, "" (Empty String), false itself, are all considered to be equivalent to false (falsy). Anything else is true (truthy).

Note that this is not uniformly supported across browsers and nodejs versions (confirm for yourself).

So two troublesome cases are the empty String "" and 0 (zero). If it is important not to override those, you might need to rewrite this as:

if (typeof obj.d == "undefined") obj.d = "default"

This will be better supported across browsers also.

Alternatively you could write this as:

obj.d ??= "default"

This is the nullish assignment which applies only to values that are null or undefined (nullish) - of which the empty string is not part. However, this has again a diminished cross-browser support.

See also on the official Mozilla Website - Assigning a default value to a variable.

If you only have an object that is a single level deep (nested object properties will not merge as expected since it directly destructures from the first level), you can use the following destructuring syntax:

const options = {
    somevar: 1234,
    admin: true
};

const defaults = {
    test: false,
    admin: false,
};

var mergedOptions = {...defaults, ...options};

Of which the output would be:

console.log(options);
// { somevar: 1234, admin: true }

console.log(mergedOptions);
// { test: false, admin: true, somevar: 1234 }

Or even formatted as a single statement (this is slightly unreadable though):

const options = {...{
    // Defaults
    test: false,
    admin: false,
}, ...{
    // Overrides
    somevar: 1234,
    admin: true
}};
Object.withDefault = (defaultValue,o={}) => {
  return new Proxy(o, {
    get: (o, k) => (k in o) ? o[k] : defaultValue 
  });
}

o = Object.withDefault(42);
o.x  //=> 42

o.x = 10
o.x  //=> 10
o.xx //=> 42

With the addition of the Logical nullish assignment operator, you can now do something like this

const obj = {}
obj.a ??= "default";

In the case where you have an empty list as the default value and want to push to it, you could do

const obj = {}
(obj.a ??= []).push("some value")

I came here looking for a solution because the header matched my problem description but it isn't what i was looking for but i got a solution to my problem(I wanted to have a default value for an attribute which would be dynamic something like date).

let Blog = {
title  : String,
image  : String,
body   : String,
created: {type: Date, default: Date.now}
}

The above code was the solution for which i finally settled.

Related