Подводя итог, два основных момента:
#P2#
#P3#
Первое, что следует отметить, это то, что с точки зрения поведения класса во время выполнения эти точки функционально не связаны друг с другом. Например, вы можете разрешить Foo()
без new
, но при этом Foo.call({})
будет вести себя так, как будто он был new
ed. Возможность вызывать как функцию может разрешить установку this
, но это не обязательно, точно так же, как Foo.bind({})()
связывает this
, а затем вызывает функцию, но связанное this
будет игнорироваться.
Что касается обоснования решения, я не могу дать вам первоисточник, но могу сказать, что есть одна веская причина. Синтаксис класса ES6 — это «синтаксический сахар», но не для упрощенного кода, который вы, вероятно, имеете в своей голове. Возьмем, к примеру, этот фрагмент, учитывая вашу цель.
class Parent {}
class Child extends Parent {
constructor() {
// What is "this" here?
super();
}
}
Child.call({});
Что это должно делать? В ES6 super()
фактически устанавливает this
. Если вы попытаетесь получить доступ к this
до вызова super()
, будет выдано исключение. Код вашего примера может работать с Base.call({})
, так как у него нет родительского конструктора, поэтому this
инициализируется заранее, но как только вы вызываете дочерний класс, this
даже не имеет значения впереди . Если вы используете .call
, это значение некуда поместить.
Итак, следующий вопрос: почему дочерние классы не получают this
раньше super()
? Это связано с тем, что он позволяет синтаксису класса ES6 расширять встроенные типы, такие как Array
, Error
и Map
, а также любой другой тип встроенного конструктора. В стандартном ES5 это было невозможно, хотя с нестандартным __proto__
в ES5 это можно было смоделировать грубо. Даже с __proto__
расширение встроенных типов обычно является проблемой производительности. Включив это поведение в классы ES6, механизмы JS могут оптимизировать код, чтобы расширение встроенных типов работало без снижения производительности.
Итак, на ваши вопросы, да, они могут разрешить Foo.call()
или Foo()
, но в любом случае придется игнорировать this
, чтобы разрешить расширение встроенных типов.
person
loganfsmyth
schedule
15.06.2017