欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【ECMAScript 学习笔记】5.关于 Class

程序员文章站 2024-03-22 17:51:22
...

Class基本语法

  ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类:

    // 定义 Point 类
    class Point {
        // 定义 Ponit 类的构造函数
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }

        // 定义方法
        toString() {
            console.log(`x:${this.x}, y:${this.y}`);
        }
    }

  ES6 的类,完全可以看作构造函数的另一种写法:

    class Point { 
        constructor() {

        }
    };

    console.log(typeof Point); // "function"

    console.log(Point === Point.prototype.constructor); // true

事实上,类的所有方法都定义在类的 prototype 属性上。在类的实例上调用方法,其实就是调用原型的方法。*

  Object.assign 方法可以向类添加多个方法:

    Object.assign(Point.prototype,{
        toValue() {},
        toString() {}
    })

ES6 中类的内部所有定义的方法,都是不可枚举的,这一点与 ES5 的行为不一致。

    class Point {
        constructor(){}
        toString(){}
    }

    console.log(Object.keys(Point.prototype)); // []

若想要获取其内部定义的所有方法,则可通过 Object.getOwnPropertyNames 方法获取

    console.log(Object.getOwnPropertyNames(Point.prototype));

  可使用表达式定义类的属性名

    let methodName = "getArea";

    class Square {
        constructor(){}

        [methodName](){}
    }

constructor 方法

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

  constructor 方法默认返回实例对象(即 this),完全可以指定返回另一个对象。

    class Foo {
        constructor() {
            return Object.create(null);
        }
    }

Class 表达式

  与函数一样, Class 也可以使用表达式的形式定义。

    const MyClass = class Me {
        getClassName() {
            return Me.name;
        }
    }

Class 的继承

  Class 之间可以通过 extends 关键字实现继承,这比 ES5 通过修改原型链实现继承,要清晰和方便很多:

    class ColorPoint extends Point {

        constructor(x,y) {
            super(x,y); // 用于表示 父类的构造函数,用来新建父类的 this 对象。
        }
    }

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

ES5 的继承,实质是先创造子类的实例对象 this,然后再将父类的方法添加到 this上(Parent.applu(this))。ES6 的继承机制完全不同,实质是先创造父类的实例对象 this(所以必须先调用 super 方法),然后再用子类的构造函数修改 this

类的 prototype 属性和 proto 属性

  大多数浏览器的 ES5 实现之中,每一个对象都有 __proto__ 属性,指向对应的构造函数的 prototype 属性。
Class 作为构造函数的语法糖,同时有 prototype__proto__ 属性,因此同时存在两条继承链:

  1. 子类的 __proto__ 属性,表示构造函数的继承,总是指向父类
  2. 子类 prototype 属性的 __proto__ 属性,表示方法的继承,总是指向父类的 prototype 属性。

Object.getPrototypeOf

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

    Object.getPrototypeOf(ColorPoint); // Ponit

super 关键字

  1. 作为函数调用时,super 代表父类的构造函数。
  2. 作为调用时,super 代表父类,可以直接引用父类实例的属性和方法,也可以引用父类的静态方法。

实例的 proto 属性

   子类实例的 __proto__ 属性的 __proto__ 属性,指向父类实例的 __proto 属性。

Class 的取值函数(getter)和存值函数(setter)

  与 ES5 一样,在 Class 内部可以使用 getset 关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

    class MyClass {
        constructor() {
            this.element = '';
        }

        get prop() {
            return this.element;
        }

        set prop(value) {
            this.element = value;
        }
    }

Class 的静态方法

  在方法前加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用。

    class MyClass {
        constructor() {
            this.element = '';
        }
        static classMethod() {
            return false;
        }
    }

    MyClass.classMethod();

new.target 属性

  new.target 属性用于确定构造函数是怎么调用的。在构造函数中返回 new 命令作用于的那个对象函数,如果不是通过 new 命令调用的,则返回 undefined

相关标签: ECMAScript es6