在调用构造函数之前是否可以知道'this'对象?

Pal*_*leo 6 javascript constructor class this ecmascript-6

在ES6类之前,函数可以用作构造函数:

function MyClass(a, b) {
}
Run Code Online (Sandbox Code Playgroud)

然后,以下代码相当于经典实例化(如let thisObj = new MyClass("A", "B")):

let thisObj = Object.create(MyClass.prototype)
// Here we know the `this` object before to call the constructor.
// Then, the constructor is called manually:
MyClass.call(thisObj, "A", "B")
Run Code Online (Sandbox Code Playgroud)

...这种技术是this在调用构造函数之前知道对象的一种方法.但是Function.prototype.call()不适用于ES6类构造函数.

有了ES6,我们有Reflect.construct():

let thisObj = Reflect.construct(MyClass, "A", "B");
Run Code Online (Sandbox Code Playgroud)

但它没有提供在this创建对象后调用构造函数的方法.

是否仍然可以使用ES6课程?

我的用例

我需要将此功能从ES5保留到ES6以获得框架.该框架负责实例化组件(这是ES6类).组件可以从其构造函数创建子组件(在组件树中,此处没有继承).然后,子组件可以查询框架以从其自己的构造函数中获取其父级.在这种情况下,我们有技术限制,因为框架仍然没有父组件构造函数的返回值.这是与ES5(转化为)相比的回归.

Est*_*ask 3

ES6 类不可能做到这一点。ES6 类应该仅使用new或进行实例化Reflect.construct

目前禁止使用函数调用类。这样做是为了为未来保留选择余地,最终添加一种通过类处理函数调用的方法。[来源:exploringjs ]

也可以看看:

为什么这种模式不可行

类实例不是this构造函数中必须出现的对象,因为 ES6 类可以从构造函数返回一个值,该值被视为类实例:

class Foo {
  constructor {
    // `this` is never used
    return {};
  }
}
Run Code Online (Sandbox Code Playgroud)

组件可以从其构造函数创建子组件。然后,子组件可以查询框架以从其自己的构造函数中获取其父组件

这种模式在 ES6 类中不可行。该限制限制this了之前出现super

为了到达层次结构中的特定类,可以使用装饰器模式在定义类时对其进行装饰。这允许修改其定义上的原型或在父类和子类之间放置一个中间类。这种方法解决了许多特定于框架的任务,例如依赖注入,并在现代框架(Angular 等)中使用。

一个方便的方法是 ECMAScript Next/TypeScript 装饰器。这是一个示例,显示装饰器允许动态拦截子构造函数并增强子原型:

let BAZ;

class Foo {
  constructor(foo) {
    console.log(foo);    
  }
}

function bazDecorator(Class) {
  return class extends Class {
    constructor(foo) {
      super(BAZ || foo);
    }

    get bar() {
      return BAZ || super.bar;
    }
  }
}

@bazDecorator
class Bar extends Foo {
  constructor(foo) {
    super(foo);

    console.log(this.bar);
  }

  get bar() {
    return 'bar';
  }
}

// original behaviour
new Bar('foo'); // outputs 'foo', 'bar'

// decorated behaviour
BAZ = 'baz';
new Bar('foo'); outputs 'baz', 'baz'
Run Code Online (Sandbox Code Playgroud)

ES.next 装饰器基本上是一个辅助函数。即使没有语法糖,它仍然适用于 ES6,但语法略有不同:

const Bar = bazDecorator(
    class Bar extends Foo { ... }
);
Run Code Online (Sandbox Code Playgroud)