Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active October 17, 2019 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rauschma/c00b747df893b8afa30bbdd0bb6357a9 to your computer and use it in GitHub Desktop.
Save rauschma/c00b747df893b8afa30bbdd0bb6357a9 to your computer and use it in GitHub Desktop.
class Point {
constructor(...args) {
switch (args.length) {
case 2: {
// Normal constructor
const [x, y] = args;
this.x = x;
this.y = y;
break;
}
case 1: {
// Copy constructor
const [other] = args;
this.x = other.x;
this.y = other.y;
break;
}
default:
throw new Error();
}
}
}
@ronkorving
Copy link

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  static copy(other) {
    return new Point(other.x, other.y);
  }
}

Always side with readability? :)

To undermine my own example however: if the constructor does any postprocessing on the input (eg: point.x not being equal to the x that goes into the constructor), my example starts to hurt.

@rauschma
Copy link
Author

@ronkorving That’s definitely better. Thanks!

@ronkorving
Copy link

ronkorving commented Oct 16, 2019

Until:

class Point {
  constructor(x, y) {
    this.x = x * 2;
    this.y = y;
  }

  static copy(other) {
    return new Point(other.x, other.y); // now the copy's x will be double other's x
  }
}

@vlilloh
Copy link

vlilloh commented Oct 16, 2019

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  clone() {
    return new Point(this.x, this.y);
  }
  static clone(point) {
    return new Point(point.x, point.y);
  }
}

class Point3D extends Point {
  constructor(x, y, z) {
    super(x, y);
    this.z = z;
  }
  clone() {
    return new Point3D(this.x, this.y, this.z);
  }
  static clone(point3d) {
    return new Point3D(point3d.x, point3d.y, point3d.z);
  }
}

What I don't know is which one is better: the instance approach ( clone()) or the class approach (static clone(point3d)). Although I prefer the instance approach, it's more concise, both in the definition and in the call, and the instance is always necessary.

@jampy
Copy link

jampy commented Oct 17, 2019

both are valid and you could even provide both

The static variant has the advantage that it plays nice with other scenarios:

const foo = Point.fromOther(otherPoint) ;// aka copy
const foo = Point.fromLineStart(line); // conversion
const foo = Point.fromMidpoint([...geometries]);
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment