4

I am building a note taking app and require a way to pass the time the user takes to a constructor function that stores it. Here is the destination:

var NoteTime = function(minute, hour, day, month, year) {
    var d = new Date();
    this.millisec = d.getMilliseconds();
    this.minute = minute || d.getMinutes();
    this.hour = hour || d.getHours();
    this.day = day || d.getDay();
    this.month = month || d.getMonth();
    this.year = year || d.getUTCFullYear();
}

var gatheredTime = {
    minute: null,
    hour: null,
    day: null,
    month: null,
    year: null
}

I know I can passgatheredTime like this

var storeResult = new NoteTime(gatheredTime[prop1], gatheredTime[prop2]....etc)

But I would like to use less code and pass the value like I would were it an array:

var storeResult = new NoteTime(...gatheredTime)

Yes I can convert it to an array, but I would like to know if there is a better way.

ssube
  • 47,010
  • 7
  • 103
  • 140
Bar Akiva
  • 1,089
  • 1
  • 11
  • 23
  • Possible duplicate of [Unlimited arguments in a JavaScript function](http://stackoverflow.com/questions/6396046/unlimited-arguments-in-a-javascript-function) – Roger Ng Aug 09 '16 at 10:09
  • There is a [proposal](https://github.com/sebmarkbage/ecmascript-rest-spread) for rest/spread properties which you may be interested in. – gcampbell Aug 09 '16 at 10:15
  • Also, you could use [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to handle defaults. – gcampbell Aug 09 '16 at 10:20
  • @gcampbell It doesn't help here though. – Bergi Aug 09 '16 at 11:55
  • @Bergi It might not solve OP's problem, but people searching who come across this question might find it helpful (especially as that's what's implied by the title). – gcampbell Aug 09 '16 at 11:58
  • @gcampbell: I guess editing the title is more appropriate in such a situation :-) – Bergi Aug 09 '16 at 11:59
  • 1
    There is no such thing as a spread *operator*. – Felix Kling Aug 09 '16 at 15:42

2 Answers2

4

Use Destructuring assignment

var NoteTime = function (gatheredTime) {
    let {minute, hour, day, month, year} = gatheredTime;

var NoteTime = function(gatheredTime) {
  let {
    minute, hour, day, month, year
  } = gatheredTime;
  console.log(minute, hour, day, month, year);
  // code here
};

var gatheredTime = {
  minute: 10,
  hour: 5,
  day: 9,
  month: 8,
  year: 2016
};

NoteTime(gatheredTime);

Alternatively, the parameters can be directly destructed in arguments.

var NoteTime = function ({minute, hour, day, month, year}) {
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
Tushar
  • 85,780
  • 21
  • 159
  • 179
  • Global variables, that's ugly. PS: you have not created a constructor. So it's not obvious how your code improves what OP has. You also don't have default values. – zerkms Aug 09 '16 at 10:12
  • @zerkms yes, Thanks to James, for direct destructing, which avoids global variables. – Tushar Aug 09 '16 at 10:14
  • @Tushar well, you could have avoided it if you declared your variables. But still, it's not obvious how your code improves anything. If you expand your examples to do what OP's code does - your one will be even more complicated. – zerkms Aug 09 '16 at 10:15
0

You might need to turn your object into iterable by adding a [Symbol.iterator] method and then you can use for of loop or spread operator over a standard JS object.. Such as;

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this),
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);

You can add the symbol iterators at the constructor so all of your instantiated objects will be iterable.

Redu
  • 25,060
  • 6
  • 56
  • 76
  • That doesn't really work for the OPs use case though, as objects are unordered and any property could end up in any parameter. – Bergi Aug 09 '16 at 11:55