Search code examples
javascriptecmascript-6destructuring

JS ES6: Get parameters as an object with destructuring


Is it possible to get the function's arguments as an object (in order to iterate on it) using destructuring?

function({a=1, b=2, c=3}={}) {
  // how to get {a:1, b:2, c:3}?
}

My goal here is to bind each parameter to this in a class constructor.

It is possible without destructuring:

class Test {
  constructor(args) {
    Object.assign(this, args);
  }
}

But I don't know how to simplify that:

class Test {
  constructor({a=1, b=2, c=3}={}) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
}

let test = new Test();
// test.a = 1 
// test.b = 2 etc.

Solution

  • You can do this, using the shorthand form of object creation:

    class Test {
      constructor({a=1, b=2, c=3}={}) {
        Object.assign(this, {a, b, c});
      }
    }
    

    Example:

    class Test {
      constructor({a=1, b=2, c=3}={}) {
        Object.assign(this, {a, b, c});
      }
    }
    const t1 = new Test();
    console.log("t1:", t1.a, t1.b, t1.c);
    const t2 = new Test({b: 42});
    console.log("t2:", t2.a, t2.b, t2.c);


    Alternately, don't use destructuring, and use multiple arguments to Object.assign:

    class Test {
      constructor(options = {}) {
        Object.assign(this, Test.defaults, options);
      }
    }
    Test.defaults = {a: 1, b: 2, c: 3};
    
    // Usage:
    const t1 = new Test();
    console.log("t1:", t1.a, t1.b, t1.c);
    const t2 = new Test({b: 42});
    console.log("t2:", t2.a, t2.b, t2.c);

    ...and if you want any of those as discrete things you can reference by name, you can either just use this.a (and this.b and this.c) to do it, or you can do:

    let {a, b, c} = this;
    

    ...afterward and use those. (Just beware that assigning to the resulting a, b, and c won't update the object.)