Какой стандартный способ вызова статических методов? Я могу думать об использовании constructor
или использовании имени самого класса, мне не нравится последний, так как он не чувствует необходимости. Первый рекомендуемый способ, или есть что-то еще?
Вот (надуманный) пример:
class SomeObject {
constructor(n){
this.n = n;
}
static print(n){
console.log(n);
}
printN(){
this.constructor.print(this.n);
}
}
javascript
class
static
ecmascript-6
es6-class
simonzack
источник
источник
SomeObject.print
чувствует себя естественно. Ноthis.n
внутри нет смысла, так как нет примера, если мы говорим о статических методах.printN
не является статичным, хотя.Ответы:
Оба способа жизнеспособны, но они делают разные вещи, когда дело доходит до наследования с переопределенным статическим методом. Выберите того, чье поведение вы ожидаете:
Ссылка на статическое свойство через класс будет фактически статической и будет постоянно давать одно и то же значение. Использование
this.constructor
вместо этого будет использовать динамическую диспетчеризацию и ссылаться на класс текущего экземпляра, где статическое свойство может иметь унаследованное значение, но также может быть переопределено.Это соответствует поведению Python, где вы можете ссылаться на статические свойства либо через имя класса, либо через экземпляр
self
.Если вы ожидаете, что статические свойства не будут переопределены (и всегда ссылаются на свойства текущего класса), как в Java , используйте явную ссылку.
источник
class
синтаксиса), в определении метода нет различий. Это просто вопрос того, как вы смотрите это, через унаследованноеconstructor
свойство или напрямую по его имени.Property 'staticProperty' does not exist on type 'Function'
Я наткнулся на эту тему в поисках ответа на аналогичный случай. В основном все ответы найдены, но все еще трудно извлечь из них основную информацию.
Виды доступа
Предположим, что класс Foo, вероятно, является производным от какого-либо другого класса (классов), возможно, с большим количеством классов, полученных из него.
Затем доступ
this.method()
this.property
Foo.method()
Foo.property
this.constructor.method()
this.constructor.property
this.method()
this.property
Foo.method()
Foo.property
Foo.prototype.method.call( this )
Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);
Задний план
this
имеет в виду текущий экземпляр.super
в основном относится к одному и тому же экземпляру, но в некоторой степени обращается к методам и получателям, написанным в контексте некоторого класса, который расширяется (используя прототип прототипа Foo).this.constructor
.this
доступно для ссылки на определение текущего класса напрямую.super
также не относится к какому-либо экземпляру, но к статическим методам и получателям, написанным в контексте некоторого класса, который расширяется.Вывод
Попробуйте этот код:
источник
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- Это очень жаль. На мой взгляд, это недостаток ES6 +. Может быть , он должен быть обновлен , чтобы просто в видуmethod
- то естьmethod.call(this)
. Лучше чемFoo.prototype.method
. Babel / др. можно реализовать с помощью NFE (выражение именованной функции).method.call( this )
является вероятным решением, за исключением того, чтоmethod
оно не привязано к желаемому базовому «классу» и, следовательно, не может быть переопределенным методом / получателем экземпляра . Таким способом всегда можно работать с независимыми от класса методами. Тем не менее, я не думаю, что современный дизайн настолько плох. В контексте объектов класса, производных от вашего базового класса Foo, могут быть веские причины для переопределения метода экземпляра. Этот переопределенный метод может иметь веские причины вызывать егоsuper
реализацию или нет. Любой случай приемлем и должен соблюдаться. Иначе это закончилось бы плохим дизайном ООП.arguments.callee
или NFE.this
). Это звучит как попытка смешать преимущества арифметики указателей голого C с C # более высокого уровня. Просто из любопытства: что бы вы использовалиarguments.callee
в чисто разработанном ООП-коде?this.inherited(currentFn, arguments);
- гдеcurrentFn
ссылка на текущую выполняемую функцию. Невозможность напрямую ссылаться на выполняемую в настоящее время функцию делает его немного затруднительным в TypeScript, который использует синтаксис своего класса из ES6.Если вы планируете заниматься каким-либо наследством, я бы порекомендовал
this.constructor
. Этот простой пример должен иллюстрировать почему:test1.callPrint()
войдетConstructorSuper Hello ConstructorSuper!
в консольtest2.callPrint()
войдетConstructorSub Hello ConstructorSub!
в консольИменованный класс не будет иметь дело с наследованием, если вы явно не переопределите каждую функцию, которая делает ссылку на именованный класс. Вот пример:
test3.callPrint()
войдетNamedSuper Hello NamedSuper!
в консольtest4.callPrint()
войдетNamedSuper Hello NamedSub!
в консольВсе вышеперечисленное работает в Babel REPL .
Из этого видно, что он
test4
все еще думает, что он в суперклассе; в этом примере это может показаться не таким уж большим делом, но если вы пытаетесь ссылаться на функции-члены, которые были переопределены, или на новые переменные-члены, вы окажетесь в беде.источник