有可能知道这个'这个'在调用构造函数之前对象?

时间:2018-04-25 13:58:22

标签: javascript class ecmascript-6 constructor this

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

function MyClass(a, b) {
}

然后,以下代码等同于经典实例化(如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")

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

使用ES6,我们有Reflect.construct()

let thisObj = Reflect.construct(MyClass, "A", "B");

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

使用ES6课程仍然可以吗?

我的用例

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

1 个答案:

答案 0 :(得分:3)

使用ES6课程是不可能的。 ES6类应该仅使用newReflect.construct进行实例化。

  

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

另见:

为什么这种模式不可行

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

class Foo {
  constructor {
    // `this` is never used
    return {};
  }
}
  

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

获取其父级

这种模式在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'

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

const Bar = bazDecorator(
    class Bar extends Foo { ... }
);