繁体   English   中英

你如何 polyfill Javascript ES6 `new.target`?

[英]How do you polyfill Javascript ES6 `new.target`?

一些 ES6 特性真的很容易 polyfill:

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

你会如何new.target 当它在不受支持的浏览器中使用时会触发语法错误。 try/catch不起作用,因为它是一个语法错误。 我不必使用new.target ,我主要只是好奇。

正如Jaromanda所评论的那样,您不能添加新的语法,但是现在您可以轻松解决一些 new.target用例

看一下new.target文档,您会看到一些可以轻松用es5编写的示例

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"

没有

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"

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"

没有

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"

希望这有所帮助

这是使用Function::bind的一种方法:

const requireNew = (() => {
  const kFake = {};
  const CtorMap = new WeakMap();
  const FuncToString = function toString () {
    const info = CtorMap.get(this);
    return Function.prototype.toString.apply(
        info ? info.ctor : this, arguments);
  };
  const GetProto = function prototype() {
    const info = CtorMap.get(this);
    return info ? info.ctor.prototype : undefined;
  };
  const SetProto = function prototype(prototype) {
    const info = CtorMap.get(this);
    return !info ? prototype
        : info.wrapper.prototype = info.ctor.prototype = prototype;
  }
  return (Ctor) => {
    const wrapper = function () {
      if (this === kFake) {
        throw new TypeError("Please use 'new' to call this");
      }
      return Ctor.apply(this, arguments);
    }
    wrapper.prototype = Ctor.prototype;
    const bound = wrapper.bind(kFake);
    CtorMap.set(bound, { ctor: Ctor, wrapper });
    Object.defineProperties(bound, {
      prototype: { get: GetProto, set: SetProto,
          enumerable: false, configurable: true },
      name: { value: Ctor.name, writable: false,
          enumerable: false, configurable: true },
      length: { value: Ctor.length, writable: false,
          enumerable: false, configurable: true },
      toString: { value: FuncToString, writable: true,
          enumerable: false, configurable: true }
    });
    return bound;
  }
})();

这是一个简单的演示:

function Abc (a) {
  this.a = a;
  console.log("this =", this, "; .a =", this.a, "; new.target:", new.target);
}
const A = requireNew(Abc);
const a = new A(1);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM