6

Some ES6 features are really easy to polyfill:

if(!Array.prototype.find){
  Array.prototype.find=...
}

How would you polyfill new.target? It triggers a syntax error when it's used in an unsupported browser. try/catch doesn't work because it's a syntax error. I don't have to use new.target, I'm mostly just curious.

Leo Jiang
  • 18,829
  • 38
  • 122
  • 215

1 Answers1

6

As Jaromanda commented, you cannot polyfill new syntax, but you can easily work around some new.target use cases for now

Taking a look at the new.target docs you'll see some examples that can easily be written with es5

with new.target

function Foo() {
  if (!new.target) throw "Foo() must be called with new";
  console.log("Foo instantiated with new");
}

Foo(); // throws "Foo() must be called with new"
new Foo(); // logs "Foo instantiated with new"

without

function Foo() {
  if (!(this instanceof Foo)) throw "Foo() must be called with new";
  console.log("Foo instantiated with new");
}

Foo(); // throws "Foo() must be called with new"
new Foo(); // logs "Foo instantiated with new"

with new.target

class A {
  constructor() {
    console.log(new.target.name);
  }
}

class B extends A { constructor() { super(); } }

var a = new A(); // logs "A"
var b = new B(); // logs "B"

without

class A {
  constructor() {
    // class forces constructor to be called with `new`, so
    // `this` will always be set
    console.log(this.constructor.name);
  }
}

class B extends A { constructor() { super(); } }

var a = new A(); // logs "A"
var b = new B(); // logs "B"

Hope this helps a little

Thank you
  • 107,507
  • 28
  • 191
  • 224
  • 1
    No, `!(this instanceof Foo)` is not a complete replacement for `new.target`. – Bergi Oct 27 '15 at 09:15
  • @Bergi could you elaborate? I highly respect your input on this site. – Thank you Oct 27 '15 at 15:53
  • I don't mean to say that it's a complete replacement but it covers two really common cases (as described on MDN). – Thank you Oct 27 '15 at 16:00
  • 1
    Yeah, I guess `instanceof` is fine and covers the typical mistake case, but still [`new.target`](http://stackoverflow.com/q/32450516/1048572) behaves different - e.g. on `foo=new Foo; foo.constructor()`. – Bergi Oct 27 '15 at 16:18
  • One case instanceof doesn't cover is abstract class instantiation. that would be `constructor(){ if (new.target === MyAbstractClass){throw TypeError('Abstract Class cannot be instantiated');` – motobói Sep 19 '16 at 18:50
  • 3
    You can rewrite an abstract class constructor like `if (this.constructor.name === MyAbstractClass.name) {throw new Error("Cannot instantiate abstract class.");}` It works great when extending ES6 classes with an abstract class. I had to do this since Babel still doesn't polyfill `new.target` so my Webpack UglifyJS plugin was reading it as a syntax error, breaking my production builds. – Chunky Chunk Apr 18 '17 at 18:59