일반 ES6 클래스 메소드에서 정적 메소드 호출
정적 메소드를 호출하는 표준 방법은 무엇입니까? 나는 constructor
클래스 자체의 이름 을 사용 하거나 사용할 것을 생각할 수 있습니다 . 필요하지 않다고 생각하기 때문에 후자를 좋아하지 않습니다. 전자가 권장되는 방법입니까, 아니면 다른 것이 있습니까?
다음은 (고려 된) 예입니다.
class SomeObject {
constructor(n){
this.n = n;
}
static print(n){
console.log(n);
}
printN(){
this.constructor.print(this.n);
}
}
두 방법 모두 실행 가능하지만 재정의 된 정적 메서드를 사용하여 상속 할 때 다른 작업을 수행합니다. 행동이 예상되는 것을 선택하십시오 :
class Super {
static whoami() {
return "Super";
}
lognameA() {
console.log(Super.whoami());
}
lognameB() {
console.log(this.constructor.whoami());
}
}
class Sub extends Super {
static whoami() {
return "Sub";
}
}
new Sub().lognameA(); // Super
new Sub().lognameB(); // Sub
클래스를 통해 정적 속성을 참조하면 실제로 정적이며 지속적으로 동일한 값을 제공합니다. 사용하여 this.constructor
동적 파견을 사용하고 정적 속성은 현재 인스턴스의 클래스를 참조 할 대신 할 수 상속 된 값을 가질뿐만 아니라, 오버라이드 (override) 할 수 있습니다.
이것은 클래스 이름이나 instance를 통해 정적 속성을 참조하도록 선택할 수있는 Python의 동작과 일치합니다 self
.
Java 에서처럼 정적 특성이 대체되지 않고 항상 현재 클래스 중 하나를 참조 할 것으로 예상되는 경우 명시 적 참조를 사용하십시오.
비슷한 사례에 대한 답을 찾기 위해이 스레드를 우연히 발견했습니다. 기본적으로 모든 답변이 있지만 여전히 필수 답변을 추출하기는 어렵습니다.
접근의 종류
아마도 다른 클래스에서 파생 된 Foo 클래스가 더 많은 클래스를 가지고 있다고 가정합니다.
그런 다음
- Foo의 정적 메소드 / getter에서
- 아마도 재정의 된 정적 메소드 / getter :
this.method()
this.property
- 아마도 재정의 된 인스턴스 메소드 / getter :
- 의도적으로 불가능
- 자신의 오버라이드 (override)되지 않는 정적의 방법 / 게터 :
Foo.method()
Foo.property
- 재정의되지 않은 자체 인스턴스 메소드 / 게터 :
- 의도적으로 불가능
- 아마도 재정의 된 정적 메소드 / getter :
- Foo의 인스턴스 메소드 / getter에서
- 아마도 재정의 된 정적 메소드 / getter :
this.constructor.method()
this.constructor.property
- 아마도 재정의 된 인스턴스 메소드 / getter :
this.method()
this.property
- 자신의 오버라이드 (override)되지 않는 정적의 방법 / 게터 :
Foo.method()
Foo.property
- 재정의되지 않은 자체 인스턴스 메소드 / 게터 :
- 일부 해결 방법을 사용하지 않으면 의도적으로 불가능합니다 .
Foo.prototype.method.call( this )
Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);
- 일부 해결 방법을 사용하지 않으면 의도적으로 불가능합니다 .
- 아마도 재정의 된 정적 메소드 / getter :
사용하는 것을 명심
this
화살표 기능을 사용하거나 메소드를 호출 할 때이 방법을 작동하지 않습니다 / 게터가 명시 적으로 사용자 정의 값에 바인딩.
배경
- 인스턴스의 메소드 또는 getter와 관련하여
this
현재 인스턴스를 참조하고 있습니다.super
is basically referring to same instance, but somewhat addressing methods and getters written in context of some class current one is extending (by using the prototype of Foo's prototype).- definition of instance's class used on creating it is available per
this.constructor
.
- When in context of a static method or getter there is no "current instance" by intention and so
this
is available to refer to the definition of current class directly.super
is not referring to some instance either, but to static methods and getters written in context of some class current one is extending.
Conclusion
Try this code:
class A {
constructor( input ) {
this.loose = this.constructor.getResult( input );
this.tight = A.getResult( input );
console.log( this.scaledProperty, Object.getOwnPropertyDescriptor( A.prototype, "scaledProperty" ).get.call( this ) );
}
get scaledProperty() {
return parseInt( this.loose ) * 100;
}
static getResult( input ) {
return input * this.scale;
}
static get scale() {
return 2;
}
}
class B extends A {
constructor( input ) {
super( input );
this.tight = B.getResult( input ) + " (of B)";
}
get scaledProperty() {
return parseInt( this.loose ) * 10000;
}
static get scale() {
return 4;
}
}
class C extends B {
constructor( input ) {
super( input );
}
static get scale() {
return 5;
}
}
class D extends C {
constructor( input ) {
super( input );
}
static getResult( input ) {
return super.getResult( input ) + " (overridden)";
}
static get scale() {
return 10;
}
}
let instanceA = new A( 4 );
console.log( "A.loose", instanceA.loose );
console.log( "A.tight", instanceA.tight );
let instanceB = new B( 4 );
console.log( "B.loose", instanceB.loose );
console.log( "B.tight", instanceB.tight );
let instanceC = new C( 4 );
console.log( "C.loose", instanceC.loose );
console.log( "C.tight", instanceC.tight );
let instanceD = new D( 4 );
console.log( "D.loose", instanceD.loose );
console.log( "D.tight", instanceD.tight );
If you are planning on doing any kind of inheritance, then I would recommend this.constructor
. This simple example should illustrate why:
class ConstructorSuper {
constructor(n){
this.n = n;
}
static print(n){
console.log(this.name, n);
}
callPrint(){
this.constructor.print(this.n);
}
}
class ConstructorSub extends ConstructorSuper {
constructor(n){
this.n = n;
}
}
let test1 = new ConstructorSuper("Hello ConstructorSuper!");
console.log(test1.callPrint());
let test2 = new ConstructorSub("Hello ConstructorSub!");
console.log(test2.callPrint());
test1.callPrint()
will logConstructorSuper Hello ConstructorSuper!
to the consoletest2.callPrint()
will logConstructorSub Hello ConstructorSub!
to the console
The named class will not deal with inheritance nicely unless you explicitly redefine every function that makes a reference to the named Class. Here is an example:
class NamedSuper {
constructor(n){
this.n = n;
}
static print(n){
console.log(NamedSuper.name, n);
}
callPrint(){
NamedSuper.print(this.n);
}
}
class NamedSub extends NamedSuper {
constructor(n){
this.n = n;
}
}
let test3 = new NamedSuper("Hello NamedSuper!");
console.log(test3.callPrint());
let test4 = new NamedSub("Hello NamedSub!");
console.log(test4.callPrint());
test3.callPrint()
will logNamedSuper Hello NamedSuper!
to the consoletest4.callPrint()
will logNamedSuper Hello NamedSub!
to the console
See all the above running in Babel REPL.
You can see from this that test4
still thinks it's in the super class; in this example it might not seem like a huge deal, but if you are trying to reference member functions that have been overridden or new member variables, you'll find yourself in trouble.
참고URL : https://stackoverflow.com/questions/28627908/call-static-methods-from-regular-es6-class-methods
'IT' 카테고리의 다른 글
사용자의 로캘 형식 및 시간 오프셋으로 날짜 / 시간 표시 (0) | 2020.06.05 |
---|---|
INT와 VARCHAR 기본 키간에 실제 성능 차이가 있습니까? (0) | 2020.06.05 |
Bash 명령 프롬프트에서 자식 분기 추가 (0) | 2020.06.05 |
@ViewChild와 @ContentChild의 차이점은 무엇입니까? (0) | 2020.06.04 |
어느 것이 더 빠르거나 가장 좋습니까? (0) | 2020.06.04 |