web-dev-qa-db-ja.com

super()の前にこれが許可されないのはなぜですか

私はReact jsでコーディングしています。ES6クラスで「これ」にアクセスするには、最初にsuper(props)を呼び出す必要があることを読みました。これがなぜであるかを知りたいのですが、答えます。スーパークラスが呼び出されない限り、Javascriptが「これ」が何であるかを知ることができないという話を主に見つけました。コンストラクタの外部では「これ」が認識され、毎回super(props)を呼び出さないため、それが何を意味するのか知りたいです。 。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { /* initial state */ };
  }
}
10
user4790067

コンストラクターメソッドは、クラスで作成されたオブジェクトを作成および初期化するための特別なメソッドです。クラスには、「コンストラクター」という名前の特別なメソッドが1つだけ存在できます。クラスにコンストラクターメソッドが複数含まれている場合、SyntaxErrorがスローされます。コンストラクターは、superキーワードを使用して、親クラスのコンストラクターを呼び出すことができます。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

つまり、_class MyComponent extends React.Component_がある場合、これを定義するには、常にsuper()呼び出しが必要です。

コンストラクターメソッドを指定しない場合は、デフォルトのコンストラクターが使用されます。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor#Default_constructors

サブクラスがthisの構成を開始する前に、thisの構成を完了するには、スーパークラスのコンストラクターをthisの前に呼び出す必要があります。そうしないと、スーパークラスコンストラクターがサブクラスによってthisを変更される可能性があります。スーパークラスはサブクラスについて何かを知っているべきではありません。そのため、コンストラクターでのsuper()呼び出しは、thisにアクセスする前に行う必要があります。

5
antono

コンストラクター関数は、デフォルトで「this」を返します。 oopsの概念によれば、子クラスは常にsuper()呼び出しによって親クラスから「this」オブジェクトを継承します。したがって、スーパーコールなしで子クラスでこれを使用しようとすると、エラーがスローされます。子クラスから「this」以外のものを返す場合、super()呼び出しは必要ありません。いくつかの簡単な例で説明しました。

例1

class A {
  constructor() {
    this.a = 0;
  }
}

class B extends A {
    constructor() {
        console.log(this);
    }
}
const instanceA = new A();
console.log(instanceA) // A {a: 0}
const instanceB = new B();
console.log(instanceB) // Error: Must call super constructor in derived class before 
accessing 'this' or returning from derived constructor 

例2

class A {
  constructor() {
    this.a = 0;
  }
}

class B extends A {
    constructor() {
      return {b: 3}
    }
}
const instanceA = new A();
console.log(instanceA) // A {a: 0}
const instanceB = new B();
console.log(instanceB) // Object {b: 3}

例3

class A {
  constructor() {
    this.a = 0;
  }
}

class B extends A {
    constructor() {
      super()
    }
}

const instanceB = new B();
console.log(instanceB) // B {a: 0}
6
Poulima Biswas

残念ながら、これは本当に複雑です。


短編小説:super()呼び出しの前のサブクラスでのthisへのアクセスは許可されていません。これは、ES6ではthisがで生まれているためです。基本クラスであるため、初期化するにはsuper()が必要です。

詳細については、 15.6.2インスタンスの割り当てと初期化 を参照してください。1。著者はこれを詳細に説明している数少ない人の一人です。

これが本からの関連サンプルです1 上記。

ボンネットの下では、おおまかに次のようになります。

// Base class: this is where the instance is allocated
function Person(name) {
    // Performed before entering this constructor:
    this = Object.create(new.target.prototype);

    this.name = name;
}
···

function Employee(name, title) {
    // Performed before entering this constructor:
    this = uninitialized;

    this = Reflect.construct(Person, [name], new.target); // (A)
        // super(name);

    this.title = title;
}
3
Lyubomir