Возможно ли узнать объект this перед вызовом конструктора? - PullRequest
0 голосов
/ 25 апреля 2018

До классов 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 голосов
/ 25 апреля 2018

Это невозможно сделать с классами ES6.Классы ES6 должны создаваться только с new или Reflect.construct.

Классы вызова функций в настоящее время запрещены.Это было сделано для того, чтобы оставить опции открытыми на будущее, чтобы в конечном итоге добавить способ обработки вызовов функций через классы.[source: exploringjs ]

См. также:

Почему этот шаблон нежизнеспособен

Экземпляр класса не нужен this объект, который появляется в конструкторе, потому что класс ES6 может возвращать значение из конструктора, который считается экземпляром класса:

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

Компонент может создавать подкомпонентыот его конструктора.Затем подкомпонент может запросить платформу, чтобы получить своего родителя от своего собственного конструктора

Этот шаблон нежизнеспособен в классах ES6.Ограничение ограничивает this от появления до super.

Чтобы достичь определенных классов в иерархии, шаблон декоратора может использоваться для украшения класса, когда он определен.Это позволяет модифицировать его прототип по определению или поместить промежуточный класс между родителем и потомком.Этот подход решает множество специфических для фреймворка задач, таких как внедрение зависимостей, и используется в современных фреймворках (Angular и т.Вот пример, который показывает, что декоратор позволяет динамически перехватывать дочерний конструктор и увеличивать дочерний прототип:

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 { ... }
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...