es6--Class:概述、属性和方法、继承

一、初识Class

1.1 Class是什么

传统面向对象的编程序语言都是【类】的概念,对象都是由类创建出来,而早期 JavaScript 中是没有类的,面向对象大多都是基于构造函数和原型实现的,但是 ECMAScript 6 规范开始增加了【类】相关的语法,使得 JavaScript 中的面向对象实现方式更加标准  

a.认识Class

 类可以看做是对象的模板,用一个类可以创建出许多不同的对象


1.2  Class的基本用法

类名一般首字母大写

语法:class 类名 {}

 // 创建类

class Person{

        // 此处编写封装逻辑

}

      class Person {}

      // 实例化类
      let re = new Person();
      console.log(re);

      let o = new Person();
      console.log(o);

      class Dog {}

      let d = new Dog();

示例:


es6--Class:概述、属性和方法、继承_第1张图片

总结:

  • 关键字 class 封装了所有的实例属性和方法

  • 类中封装的并不是变量和函数,因此不能使用关键字 letconstvar


1.3 constructor()

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法

一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加

class Point {
}

// 等同于
class Point {
  constructor() {}
}

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

类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行

总结:

  • constructor 是类中固定的方法名

  • constructor 方法在实例化时立即执行

  • constructor 方法接收实例化时传入的参数

  • constructor 并非是类中必须要存在的方法

 


1.4 Class与构造函数

类:

         //类
        class Person {

            constructor(name, age) {
                this.name = name;
                this.age = age;

                // this.speak = () => {};
            }

            speak() {
                console.log('speak');
            }

            run() {}
        }

        //类也可以在其圆形上声明方法(不推荐这种写法)
        Person.prototype.run = function() {};

        console.log(typeof Person);

        console.log(Person.prototype.speak); //类也可以在其圆形上找到该方法

es6--Class:概述、属性和方法、继承_第2张图片

构造函数:


1.5 Class的两种定义形式

a.声明形式

 class Person {

            constructor() {}

            speak() {}

        }

b.表达式形式

const Person = class {

            constructor() {

                console.log('constructor');

            }

            speak() {}

        };

        new Person();

c.立即执行的匿名类

new(class {

            constructor() {

                console.log('constructor');

            }

        })();


1.6 取值函数(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
            // 'gette


 二、Class的属性和方法

2.1 实例属性和实例方法、静态属性和静态方法

a.实例属性

方法就是值为函数的特殊属性

 class Person {

            //设置默认属性
            age = 14;
            name = 'zhangsan';
            sex = 'male';

            //实例方法
            getSex = function() {
                return this.sex;
            };

            //在这里可以对默认属性进行修改
            constructor(name, sex) {
                this.name = name;
                this.age = 18;
                this.sex = sex;
            }

            // speak() {
            //     this.age = 18;
            // }
        }

        const p = new Person('Alex');
        console.log(p.name);
        console.log(p.age);

es6--Class:概述、属性和方法、继承_第3张图片

b.静态方法和静态属性

类相当于实例的原型,所有在类中定义的方法,都会被实例继承

如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”

静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性

es6--Class:概述、属性和方法、继承_第4张图片

 

总结:

  • static 关键字用于声明静态属性和方法

  • 静态属性和方法直接通过类名进行访问

 


2.2 私有属性和方法

a.为什么需要私有属性和方法

私有方法和私有属性,是只能在类的内部访问的方法和属性,外部不能访问

 一般情况下,类的属性和方法都是公开的

公有的属性和方法可以被外界修改,造成意想不到的错误

示例:

 class Person {
            //实例属性
            constructor(name) {
                this.name = name;
            }

            //实例方法
            speak() {
                console.log('speak');
            }

            // 实例方法
            getName() {
                return this.name;
            }
        }

        //实例化属性
        const p = new Person('Alex');

        console.log(p.name);

        p.speak();

        // ....
        p.name = 'zs';
        console.log(p.name);

es6--Class:概述、属性和方法、继承_第5张图片

b.模拟私有属性和方法

1._ 开头表示私有(不具备很强的约束力)

 class Person {
            constructor(name) {
                this._name = name;
            }

            speak() {
                console.log('speak');
            }

            getName() {
                return this._name;
            }
        }

        const p = new Person('Alex');
        console.log(p.name);

        p.name = 'zd';
        console.log(p.getName());

es6--Class:概述、属性和方法、继承_第6张图片

2.将私有属性和方法移出类(具有很强的约束力)

es6--Class:概述、属性和方法、继承_第7张图片


三、Class的继承

一种简单的继承:

 //一种简单的继承,通过拷贝其原型来实现
        var lynkCoProtype = {
            model: "领克",
            getModel: function() {
                console.log("车辆模具是:" + this.model);
            }
        };

        var volvo = Object.create(lynkCoProtype, {
            model: {
                value: "沃尔沃"
            }
        });

        volvo.getModel();

es6--Class:概述、属性和方法、继承_第8张图片

3.1 extends

子类继承父类

es6--Class:概述、属性和方法、继承_第9张图片

注意:

子类必须在constructor方法中调用super方法,否则新建实例时会报错

这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法

如果不调用super方法,子类就得不到this对象

在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错--这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例


 改写继承的属性或方法

 

es6--Class:概述、属性和方法、继承_第10张图片


3.2 super

super这个关键字,既可以当作函数使用,也可以当作对象使用,就是用来调用父类的方法或属性

在继承的过程中子类中 constructor 中必须调 super 函数,否则会有语法错误

a.作为函数调用

代表父类的构造方法,只能用在子类的构造方法中,用在其他地方就会报错

super 虽然代表了父类的构造方法,但是内部的 this 指向子类的实例

es6--Class:概述、属性和方法、继承_第11张图片


b.作为对象使用

b.1.在构造方法中使用或一般方法中使用:

super 代表父类的原型对象 Person.prototype

所以定义在父类实例上的方法或属性,是无法通过 super 调用的

通过 super 调用父类的方法时,方法内部的 this 指向当前的子类实例

 class Person {
            constructor(name) {
                this.name = name;

                console.log(this);
            }

            speak() {
                console.log('speak');
                // console.log(this);
            }

            static speak() {
                console.log('Person speak');
                console.log(this);
            }
        }

        class Programmer extends Person {
            constructor(name, sex) {
                super(name, sex);

                // console.log(super.name);
                // super.speak();
            }

            // hi() {
            //   super(); // ×
            // }

            speak() {
                super.speak();
                console.log('Programmer speak');
            }
        }
        new Programmer();

b.2.在静态方法中使用:

指向父类,而不是父类的原型对象

通过 super 调用父类的方法时,方法内部的 this 指向当前的子类,而不是子类的实例

 class Person {
            constructor(name) {
                this.name = name;

                console.log(this);
            }

            speak() {
                console.log('speak');
                // console.log(this);
            }

            static speak() {
                console.log('Person speak');
                console.log(this);
            }
        }

        class Programmer extends Person {
            constructor(name, sex) {
                super(name, sex);

                // console.log(super.name);
                // super.speak();
            }

            // hi() {
            //   super(); // ×
            // }

            speak() {
                super.speak();
                console.log('Programmer speak');
            }


            static speak() {
                super.speak();
                console.log('Programmer speak');
            }
        }
        // new Person();
        // new Programmer();
        Programmer.speak();

es6--Class:概述、属性和方法、继承_第12张图片

c.注意事项

使用 super 的时候,必须显式指定是作为函数还是作为对象使用,否则会报错

 

你可能感兴趣的:(es6,ES6)