浅谈 ES6 中的 Class

2020-12-18  本文已影响0人  前端好有趣

class以及super方法

  1. super关键字单独出现在子类的构造函数中,作用是通过调用父类的构造函数来为子类添加属性和赋值

    class Father{
        constructor(x, y){
            this.x = x;
            this.y = y;
            this.name = 'Father'
        }
        sayName(){
            console.log(this.name)
        }
    }
    class Child extends Father{
        constructor(x, y){
            super(x, y);
            this.name = 'Child';
        }
        sayPosition(){
            console.log(`x:${this.x},y:${this.y}`);
        }
    }
    var demo =  new Child(5,10);
    demo; // Child { x: 5, y: 10, name: 'Child' } 子类Child通过super得到了Father的x和y属性
    demo.sayPosition(); // x:5,y:10 ,sayPosition方法里面的this指向实例demo对象
    
  2. 父类和子类之间方法和属性的相互访问

    1. 父类静态方法访问父类静态方法用this.staticfunctionMethod 来获取
    2. 父类非静态方法访问父类静态方法用this.constructor.staticfunctionMethod 来获取
    3. 父类非静态方法访问父类非静态方法用this.functionMethod 来获取
    4. 子类静态方法访问父类静态方法用super.staticfunctionMethod 来获取
    5. 子类非静态方法访问父类静态方法用super.constructor.staticfunctionMethod 来获取
    6. 子类非静态方法访问父类非静态方法用super.functionMethod 来获取
    7. 子类访问父类属性需要使用 super.constructor.Property
    class Father{
        constructor(x, y){
            this.x = x;
            this.y = y;
            this.name = 'Father'
        }
        sayName(){
            console.log(this.name)
        }
        static ping(){
            return 'ping';
        }
        static bing(){
            // 静态方法中直接使用 this.staticMethod 来访问父类的静态方法
            console.log(`bing,${this.ping()}`);
        }
        unStatic(){
            // 非静态方法中使用 this.constructor.staticMethod 来访问静态方法
            console.log(this.constructor.ping());
        }
    }
    Father.bing(); // bing,ping
    new Father().unStatic();// ping
    
    
    class Child extends Father{
        constructor(x, y){
            super(x, y);
            this.name = 'Child';
        }
        test(){
            // 子类不能直接访问父类属性,子类访问父类属性需要使用 `super.constructor.Property
            console.log(super.name,super.constructor.name);
        }
        sayName(){
            // 在子类的非静态方法中访问父类静态方法用super.constructor.staticfunctionMethod
            console.log(super.constructor.ping());
            // 在子类的非静态方法中访问父类非静态方法用super.functionMethod
            super.sayName();
        }
        static bing(){
            // 在子类的静态方法中访问父类静态方法用super.staticfunctionMethod
            console.log(`bing,${super.ping()}`);
        }
    }
    new Child().test(); // undefined,"Father"
    new Child().sayName(); // ping, Child
    Child.bing(); // bing,ping
    
  3. thissuper的区别

    • this关键词指向的是函数所在的当前对象
    • super指向的是当前对象的原型对象---------------原型对象是指Fatherprototype或者 new Child 的__proto__
    //super.name指向的是原型对象person 中的name,但是绑定的this还是当前的man对象
    const person = {
     age:'20多了',
     name(){
         return this.age;
     }
    }
     
    const man = {
     age:'18岁了',
     sayName(){
         return super.name();
     }
    }
     
    Object.setPrototypeOf( man, person );
     
    let n = man.sayName();
     
    console.log( n ) // 18岁了
    
    // Object.getPrototypeOf(this)指向的是name所在的person对象,绑定的name函数中的this也是person
    const person = {
     age:'20多了',
     name(){
         return this.age;
     }
    }
     
    const man = {
     age:'18岁了',
     sayName(){
            // 这里的this是指的man这个对象{age: 18岁了,sayName:f()}
            // Object.getPrototypeOf(this)指的是man这个对象的__proto__(person---{age: 20多了,name:f()})
         return Object.getPrototypeOf(this).name();
            // 这个返回的是 18岁了,用call改变了函数name的执行范围为man对象{age: 18岁了,sayName:f()}
            return Object.getPrototypeOf(this).name.call(this)
     }
    }
     // 把man的__proto__指向person---{age: 20多了,name:f()},用于改变man的原型指向
    Object.setPrototypeOf( man, person );
     
    let n = man.sayName();
     
    console.log( n ) // 20多了
    
  1. super在静态方法之中指向父类,在普通方法之中指向父类的原型对象(非静态方法才会在原型对象上)

    class Parent {
        // 在Parent.ccc()调用,调用Parent.bbb()报错 warning: Parent.bbb is not a function
     static ccc(msg) {
         console.log('static', msg);
     }
        // bbb()在Parent的实例上才会有   
     bbb(msg) {
         console.log('non-static-instance', msg);
     }
    }
    class Child extends Parent {
     // aaa()在Child的实例上才会有   
        aaa(msg) {
            super.bbb(msg);
        }
      // 在Child.AAA()调用,调用Child.aaa()报错 warning: Child.aaa is not a function
     static AAA(msg) {
         super.ccc(msg);
     }
    }
    
    Child.AAA(1); // static 1
    Child.aaa(1); // warning: Child.aaa is not a function
     
    var child = new Child();
    child.aaa(2); // non-static-instance 2
    console.log(111,Child.prototype)   // aaa: ƒ aaa(msg)
    console.log(222,child.__proto__)   // aaa: ƒ aaa(msg)
    console.log(333,Parent.prototype)  // bbb: ƒ bbb(msg)
    
上一篇下一篇

猜你喜欢

热点阅读