JS学習ノート-Extens

5461 ワード

基本的な使い方
ES 6のクラスは、構文糖にすぎないと考えられ、その本質はやはり構造関数+プロトタイプチェーンの組合せ式継承である.ES 6定義クラス
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
解析後、以下と同じです.
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};
ES 6ではクラスの継承方式について、extendsのキーワードを導入しました.
例:
class A {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getName() {
        return this.name;
    }
}

class B extends A {
    constructor(name, age) {
        super(name, age);
        this.job = "IT";
    }
    getJob() {
        return this.job;
    }
    getNameAndJob() {
        return super.getName() + this.job;
    }
}

var b = new B("Tom", 20);
console.log(b.name);
console.log(b.age);
console.log(b.getName());
console.log(b.getJob());
console.log(b.getNameAndJob());
//  :Tom,20,Tom,IT,TomIT
重点解析のextensキーワード上のコードは、上記のBクラス(クラス)を定義しています.このクラスはextensキーワードを通じて、Aクラスのすべての属性と方法を継承しています.Aクラスのすべての方法はデフォルトではBのプロトタイプに追加されますので、extens継承の本質はまだプロトタイプチェーンです.
テストコード:
console.log("constructor" in b);
console.log("getName" in b); 
console.log(b.hasOwnProperty("getName"));
console.log(b.hasOwnProperty("constructor"));
//  :true,true,false,false
     super   
superというキーワードは、関数としてもオブジェクトとしても使用できます.関数として使用する場合、superは親の構造関数を表し、サブクラスでPartent.applyを実行し、親のインスタンスオブジェクトの属性と方法をサブクラスのthisに追加します.以下の3つの点は特に注意が必要です.
  • サブクラスは、constructor方法でsuper方法を呼び出す必要があり、サブクラスがconstructor方法を定義していない場合、construtor方法およびその内部のsuper方法がデフォルトで追加されます.テストコード:
  • class A {
       constructor(name, age) {
           this.name = name;
           this.age = age;
       }
       getName() {
           return this.name;
       }
    }
    
    class B extends A {}
    
    var b = new B("Tom", 20);
    
    console.log(b.name);
    console.log(b.age);
    console.log(b.getName());
    console.log(b.hasOwnProperty("name"));
    //  :Tom,20,Tom,true
    
  • サブクラスのconstructor方法では、superを呼び出してから、thisキーワードを使用できます.そうでないとエラーが発生します.テストコード:
  • class A {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
    }
    
    class B extends A {
        constructor(name, age) {
            this.job = "IT";
            super(name, age);
        }
    }
    
    var b = new B("Tom", 20)
    //  :  
    
  • super()はサブタイプのconstructorの方法の中でしか使えません.他のところで使うとエラーが発生します.テストコード:
  • class A {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
    }
    
    class B extends A {
        toStr(name, age) {
            super(name, age)
        }
    }
    
    var b = new B("Tom", 20)
    //  :  
    
    superを対象とする場合は、サブクラスで親類の原型オブジェクトを指します.super=Part.prototypeです.
    テストコード:
    class A {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        getName() {
            console.log(this.name);
        }
    }
    A.prototype.n = 2;
    
    class B extends A {
        constructor(name, age) {
            super(name, age);
        }
        toStr() {
            return super.n;
        }
        activeGetName() {
            super.getName();
        }
    }
    
    var b = new B("Tom", 20);
    console.log(b.toStr());
    console.log(b.activeGetName());
    //  :2,Tom
    
    重点解析の静的方法の継承:一つの方法の前にキーワードstaticを加えると、この方法はインスタンスに継承されないということです.例:
    class A {
        static say() {
            console.log("hello");
        }
    }
    
    class B extends A {}
    
    console.log(B.say());
    //  :hello
    
    superを使用して、サブクラスの静的方法で親クラスの静的方法を呼び出すこともできる.superは、静的な方法では、親タイプのプロトタイプのオブジェクトではなく、親自身を指す.例:
    class A {
        static say() {
            console.log("hello");
        }
    }
    
    class B extends A {
        static toStr() {
            super.say();
        }
    }
    var b = new B();
    console.log(B.toStr());
    //  :hello
    
    式のクラスを継承
    クラスは他のクラスから継承できるだけでなく、式を継承することもできます.式が関数として解析され、newキーワードによって新しいインスタンスオブジェクトが作成されます.
    例1:伝統的な形を受け継ぐ構造関数
    let Obj = function(name) {
        this.name = name;
    }
    Obj.prototype.getName = function() {
        console.log(this.name);
    }
    
    class Person extends Obj {
        constructor(name, age) {
            super(name);
            this.age = age;
        }
    }
    
    const p = new Person("Tom", 19);
    
    console.log(p.name); //  :Tom
    console.log(p.age); //  :19
    p.getName(); //  :Tom
    
    例2:継承関数戻り結果
    let fn = function() {
        return class Person {
            constructor(name) {
                return {
                    name
                }
            }
        }
    }
    
    class SomeOne extends fn() {
        constructor(name) {
            super(name);
        }
    }
    
    let p = new SomeOne("Tom");
    console.log(p.name); //  :Tom
    
    New.target
    関数の内部にnew.targetオブジェクトがあることを知っています.関数がnewキーワードで呼び出されたかどうかを判断します.クラス構造関数は、new.targetによってクラスの呼び出し形式を決定することもできる.
    例:
    class Obj {
        //new Obj() ,new.target    Obj
        constructor() {
            if (new.target === Obj) {
                console.log("         !");
            }
        }
        fn() {
            console.log(this.name);
        }
    }
    
    class Person extends Obj {
        //new Person("Tom") ,new.target    Person
        constructor(name) {
            super();
            this.name = name;
        }
    }
    
    let p1 = new Person("Tom");
    p1.fn(); //  :Tom
    let p2 = new Obj(); //  :         !
    
    *クラスはnewキーワードで呼び出さなければならないので、クラスの構造関数でnew.targetの値は永遠にundefinedではない.
    http://www.imooc.com/article/79235