简体   繁体   中英

How can I make javascript class object's attribute in the parameter optional?

I am trying to create a class that doesn't need any parameters but parameters are optional. The parameters contain a single object that will be restructured. I also want users not to have to reenter the whole options list if they want to override only one of the default options. Here is the code I reached so far:

class A {
  /**
   * @param {number} path The directory path to store at.
   * @param {boolean} timeStamp The value to check if timestamps are needed.
   */
  constructor({ path, timeStamp } = { path: "./", timeStamp: true }) {
    Object.defineProperty(this, "path", { writable: false, value: path });
    Object.defineProperty(this, "timeStamp", { writable: false, value: timeStamp });
  }
}

but this doesn't work as intended. I had in mind something like this:

const y = new A({ path: "./here", timeStamp: false });
console.log(y.path); // Logs "./here". As expected
console.log(y.timeStamp); // Logs  "false". As expected

const x = new A({ timeStamp: false });
console.log(x.path); // Logs "undefined". Should be the default value  "./"
console.log(x.timeStamp); // Logs "false". As expected

const z = new A();
console.log(z.path); // Logs "./". As expected
console.log(z.timeStamp); // Logs "true". As expected

Thanks in advance.

Edit: I don't want to use many parameters, the class will eventually have many options. Here is what I am trying to accomplish: Electron's BrowserWindow documentations

You're initializing the whole object if it is not passed, what you actually wanna do is to initialize the destructured properties with a default value:

 constructor({ path = "./", timeStamp = true } = { })

Set up the constructor with two parameters with respective default values instead:

constructor(path = "./", timeStamp = true)

Here is how I would do it

const defaultOptions =  { path: "./", timeStamp: true };
class A {
  /**
   * @param {number} path The directory path to store at.
   * @param {boolean} timeStamp The value to check if timestamps are needed.
   */
  constructor(options = { }) {
    const { path, timeStamp } = Object.assign({}, defaultOptions, options);
    Object.defineProperty(this, "path", { writable: false, value: path });
    Object.defineProperty(this, "timeStamp", { writable: false, value: timeStamp });
  }
}

You set an object with default values, and receive an object as parameter which is initialized empty.

Use Object.assign to "inherit" the values. The first parameter is an empty object as it is the target that receives the properties from the other objects. Set the passed options after the defaults so they override them.

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