2

I have a little class that extends the Date object in JavaScript. One method just returns the current Date in UTC.

Date.prototype.nowUTC = function(options) {

    var now = new Date();

    return new Date(now.getUTCFullYear(), 
                    now.getUTCMonth(), 
                    now.getUTCDate(), 
                    now.getUTCHours(), 
                    now.getUTCMinutes(), 
                    now.getUTCSeconds());
}

What I'd like to do is define the options parameter as an object that will contain hours, minutes, and seconds, which will be added to the time. For example,

Date.prototype.nowUTC = function(options) {

    var now = new Date();

    return new Date(now.getUTCFullYear(), 
                    now.getUTCMonth(), 
                    now.getUTCDate(), 
                    now.getUTCHours() + options.hours, 
                    now.getUTCMinutes() + options.minutes, 
                    now.getUTCSeconds()) + options.seconds;
}

Is there a way to pre-define these values, so I don't have to check if it's defined before adding it or set a default? (such as function(options = {'hours' : null, 'minutes' : null, 'seconds' : null) {}) Id prefer to handle the parmeter like - as one object - instead of passing separate params for each value.

Thank you!

dzm
  • 22,844
  • 47
  • 146
  • 226

3 Answers3

3

You can make a little iterator to check the object properties:

Date.prototype.nowUTC = function(options) {

    // Object holding default values for this function
    var defaults = {
      "hours": <default>,
      "minutes": <default>,
      "seconds": <default>
    };

    // Iterate over the options and set defaults where the property isn't defined.
    for (var prop in defaults)  {
      options[prop] = options[prop] || defaults[prop];

      // Note: if options would contain some falsy values, you should check for undefined instead.
      // The above version is nicer and shorter, but would fail if, for example, 
      //    options.boolVal = false
      //    defaults.boolVal = true
      // the defaults would always overwrite the falsy input property.
      options[prop] = typeof options[prop] !== 'undefined' ? options[prop] : defaults[prop];
    }

    var now = new Date();
    // Rest of your function, using the options object....
};
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
2

Similar to Object.assign, you can use spread syntax:

const func = (options = {}) => {
  options = {
    foo: 1,
    bar: 2,
    baz: 3,
    ...options
  };
  console.log(options);
};

func({baz: "c", foo: "a"});

Or destructuring:

const func = ({foo = 1, bar = 2, baz = 3} = {}) => {
  console.log(foo, bar, baz);
};

func({baz: "c", foo: "a"});

Although perhaps not quite an exact duplicate, Set a default parameter value for a JavaScript function is a great canonical to browse through.

Regarding Date.prototype.nowUTC, it's considered poor practice to modify library prototypes.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
1

Object.assign is the easiest way to assign values to an objects and extend that object with input.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

So in your case:

Date.prototype.nowUTC = function(options) {

    var defaults = {
        hours: 0,
        minutes: 0,
        seconds: 0,
    };
    var now = new Date();

    options = Object.assign(defaults, options);

    return new Date(now.getUTCFullYear(), 
                    now.getUTCMonth(), 
                    now.getUTCDate(), 
                    now.getUTCHours() + options.hours, 
                    now.getUTCMinutes() + options.minutes, 
                    now.getUTCSeconds()) + options.seconds;
}
Greg Pike
  • 91
  • 7