美文网首页
ES6的Class(类)

ES6的Class(类)

作者: HW_____T | 来源:发表于2017-09-07 15:09 被阅读0次

    注:此篇文章是我参考阮一峰老师的[ECMAScript 6 入门]文章,自己记录的笔记,详细的内容请移步阮一峰老师的文章。

    1. CLASS

    在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

    class Point {
      constructor() {
        // ...
      }
    
      toString() {
        // ...
      }
    
      toValue() {
        // ...
      }
    }
    
    // 等同于
    
    Point.prototype = {
      constructor() {},
      toString() {},
      toValue() {},
    };
    

    由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面 Object.assign方法可以很方便地一次向类添加多个方法。

    class Point {
      constructor(){
        // ...
      }
    }
    
    Object.assign(Point.prototype, {
      toString(){},
      toValue(){}
    });
    

    prototype对象的constructor属性,直接指向“类”的本身,这与 ES5 的行为是一致的。

    Point.prototype.constructor === Point //

    • contructor

    constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

    • 类的实例

    实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)

    class people {
            constructor(x,y){
                this.x =x ;
                this.y =y
            }
            sayNum(){
                console.log(this.x)
            }
        }
        
        let wt =new people(1,2);
        wt.sayNum()
        console.log(wt.hasOwnProperty('x'))  //true
        
        function hasPrototypeProperty(obj,pro){
            return !obj.hasOwnProperty(pro)
        }
        console.log(hasPrototypeProperty(wt,'sayNum')) //true
    

    Class 的取值函数(getter)和存值函数(setter)
    与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

    class MyClass {
      constructor() {
        // ...
      }
      get prop() {
        return 'getter';
      }
      set prop(value) {
        console.log('setter: '+value);
      }
    }
    
    let inst = new MyClass();
    
    inst.prop = 123;
    // setter: 123
    
    inst.prop
    // 'getter'
    
    • CLASS继承
    class people {
            constructor(x,y){
                this.x =x ;
                this.y =y
            }
            sayNum(){
                console.log(this.x)
            }
        }
        
        class student extends people {
            constructor(x,y){
                super(x,y) //会调用父类的构造函数
            }
            saydNum(){
                super.sayNum()
            }
        }
        let mj=new student(101,102)
        mj.saydNum()
    

    super它在这里表示父类的构造函数,用来新建父类的this对象。

    子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

    另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。

    • Object.getPrototypeOf()

    Object.getPrototypeOf方法可以用来从子类上获取父类。

    Object.getPrototypeOf(ColorPoint) === Point
    // true
    

    因此,可以使用这个方法判断,一个类是否继承了另一个类

    • super

    super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。
    第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。

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

    上面代码中,子类B的构造函数之中的super(),代表调用父类的构造函数。这是必须的,否则 JavaScript 引擎会报错。

    注意,super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。

    第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

    class A {
      p() {
        return 2;
      }
    }
    
    class B extends A {
      constructor() {
        super();
        console.log(super.p()); // 2
      }
    }
    
    let b = new B();
    

    这里需要注意,由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。

    class A {
      constructor() {
        this.p = 2;
      }
    }
    
    class B extends A {
      get m() {
        return super.p;
      }
    }
    
    let b = new B();
    b.m // undefined
    

    上面代码中,p是父类A实例的属性,super.p就引用不到它。

    如果属性定义在父类的原型对象上,super就可以取到。

    class A {}
    A.prototype.x = 2;
    
    class B extends A {
      constructor() {
        super();
        console.log(super.x) // 2
      }
    }
    
    let b = new B();
    

    如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。

    class Parent {
      static myMethod(msg) {
        console.log('static', msg);
      }
    
      myMethod(msg) {
        console.log('instance', msg);
      }
    }
    
    class Child extends Parent {
      static myMethod(msg) {
        super.myMethod(msg);
      }
    
      myMethod(msg) {
        super.myMethod(msg);
      }
    }
    
    Child.myMethod(1); // static 1
    
    var child = new Child();
    child.myMethod(2); // instance 2
    

    相关文章

      网友评论

          本文标题:ES6的Class(类)

          本文链接:https://www.haomeiwen.com/subject/rpeijxtx.html