【ES】笔记-Class类剖析

Class

ES6提供了更接近传统语言的写法,引入Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是亿个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

知识点:

  1. class 声明类
    2.constructor 定义构造函数初始化
    3.extends 继承父类
    4.super 调用父级构造方法
    5.static 定义静态方法和属性
    6.父类方法可以重写

Class介绍与初体验

ES5 通过构造函数实例化对象

javascript 复制代码
    <script>
        //1.ES5 通过构造函数实例化对象
        //手机
        function Phone(brand,price){
            this.brand=brand;
            this.price=price;
        }
        //通过原型对象添加方法
        Phone.prototype.call=function(){
            console.log("我可以打电话!!");
        }

        //实例化对象
        let Huawei=new Phone('华为',5999);
        Huawei.call();
        console.log(Huawei);
    </script>

ES6 通过Class中的constructor实列化对象

javascript 复制代码
    <script>
        //2.class
        class Shouji{
            //构造方法 名字不能被修改
            //实例化时会自动执行
            constructor(brand,price){
                this.brand=brand;
                this.price=price;
            }

            //方法必须使用该语法,不能使用ES5的对象完整形式
            call(){
                console.log("我可以打电话!!");
            }
        }

        let onePlus=new Shouji("1+",1999);
        console.log(onePlus);
    </script>


注意事项:

  • Class必须通过constructor定义属性
  • 方法直接写就行,在class里面创建方法也不需要写function关键字,也不需要用this

Class 静态成员

实例对象与函数对象的属性不相通

javascript 复制代码
        function Phone(){

        }
        Phone.name='手机';
        Phone.change=function(){
            console.log("我可以改变世界");
        }
        let nokia=new Phone();
        console.log(nokia.name);//打印undefined
        nokia.change(); //打印Uncaught TypeError: nokia.change is not a function
 

实例对象与函数对象原型上的属性是相通的

javascript 复制代码
        function Phone(){

        }
        //构造函数本身也是对象
        //函数对象的属性,只属于函数对象,这样的属性称之为静态成员
        Phone.name='手机';
        Phone.change=function(){
            console.log("我可以改变世界");
        }
        Phone.prototype.size='5.5inch';
        let nokia=new Phone();
        console.log(nokia.size);//打印5.5inch

Class中对于static 标注的对象和方法不属于实列对象,属于类。

javascript 复制代码
        class Phone{
            static name='手机';
            static change(){
                console.log("我可以改变世界");
            }
        }

        let nokia =new Phone();
        console.log(nokia.name); //打印:undefind
        console.log(Phone.name);//打印:手机

以class方法展示,因为ES6明确规定,Class内部只有静态方法,没有静态属性,而要想得到设置静态属性,需要在实例属性前面加上 static 关键字;静态方法也要加上 static 关键字,表示该方法不会被实例继承,而是直接通过类来调用。

ES5构造函数继承

javascript 复制代码
        //手机
        function Phone(brand,price){
            this.brand=brand;
            this.price=price;
        }

        Phone.prototype.call=function(){
            console.log("我可以打电话");
        }

        //智能手机
        function SmartPhone(brand,price,color,size){
            Phone.call(this,brand,price);
            this.color=color;
            this.size=size;
        }

        //设置子级构造函数的原型
        SmartPhone.prototype=new Phone;
        SmartPhone.prototype.constructor=SmartPhone;

        //声明子类的方法
        SmartPhone.prototype.photo=function(){
            console.log("我可以拍照");
        }
        SmartPhone.prototype.playGame=function(){
            console.log("我可以玩游戏");
        }

        const chuizi=new SmartPhone('',2499,'黑色','5.5inch');
        console.log(chuizi);

Class的类继承

extends 关键字

贴合传统语言面向对象的写法

javascript 复制代码
        /*
            代码简洁,非常贴合传统语言面向对象的写法
        */
        class Phone{
            //构造方法
            constructor(band,price){
                this.band=barnd;
                this.price=price;
            }
            //父类的成员属性
            call(){
                console.log("我可以打电话!!");
            }
        }

        class SmartPhone extends Phone{
            //构造方法
            constructor(band,price,color,size){
                super(band);//父类的构造方法
                this.color=color;
                this.size=size;
            }
            photo(){
                console.log("拍照");
            }
            playGame(){
                console.log("玩游戏");
            }
        }

        const xiaomi=new SmartPhone('小米',799,'黑色','4.7inch');
        console.log(xiaomi);
        xiaomi.call();
        xiaomi.photo();
        xiaomi.playGame();

class可以通过 extends 关键字实现继承,让子类继承父类属性和方法,可以看出 extends 的写法比上文 原型链继承 清晰方便的多。

super 关键字

上面代码用到 super 这个关键字,这里简单说明一下:子类继承父类的 constructor() 构造函数中必须要有 super(),代表调用父类的构造函数,没有就会报错,super虽然代表父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类的实例。作为函数时,super() 只能用在子类的构造函数中,用在其他地方就会报错

判断继承是否存在

Object.getPrototypeOf()方法可以用来从子类上获取父类,所以可以用来判断一个类是否继承另一个类。

javascript 复制代码
<script>
    class people {}
    class boy extends people {}
    console.log(Object.getPrototypeOf(boy) === people);//true
</script>

私有属性和方法继承

私有属性和方法只能定义在它本身的class里面使用,所以子类会继承父类所有的属性和方法除了私有属性和方法,那么如何让子类访问到父类中的私有属性和方法呢?如果父类定义了私有属性的读写方法,子类就可以通过这些方法,读取私有属性。

javascript 复制代码
<script>
    class people {
        #name = '张三'
        // 定义用来读取私有属性和方法的函数
        getName(){
            return this.#name
        }
    }
    class boy extends people {
        constructor(){
            // 调用父类的构造函数
            super()
            console.log(this.getName());//张三
        }
    }
    let b = new boy()
</script>

子类对父类方法的重写

类似于Java,C#,C++面向对象语言,子类也可以对父类方法的重写。区别的时候面向对象通常使用overwrite关键字标记这个重写的方法。而ES6中则直接标记与父类的同名方法。

javascript 复制代码
        class SmartPhone extends Phone{
            //构造方法
            constructor(band,price,color,size){
                super(band);//父类的构造方法
              ...
            }
            ....
            call(){
                console.log('我可以进行视频通话');
            }
        }

注意:普通的成员方法中是不可以调用super()

Class中的getter和setter设置

在ES6中,类的内部可以使用 getter (取值函数) 和 setter (存值函数) 关键字,即 get 和 set ,对某个属性设置取值函数和存值函数,拦截该函数的存取行为。

javascript 复制代码
        //get 和set 对对象属性方法的绑定
        class Phone{
            get price(){
                console.log("价格属性被读取了");
                return 'iloveyou' //get 有返回值
            }
            set price(newVal){
                console.log("价格属性被修改了");
            }
        }
        
        //实列化对象
        let s=new Phone();
        console.log(s.price);

        s.price='free';

class显示原型与隐式原型关系

每个对象都有隐式原型 proto 属性,指向对应的构造函数的显示原型 prototype 属性,class作为构造函数的语法糖,同时也具有 prototype 属性和 proto 属性,所以存在两条继承链。当然这里这做一个了解。

javascript 复制代码
<script>
    class people {}
    class boy extends people{}
    
    // 子类的__proto__属性,表示构造函数的继承,总是指向父类。
    console.log(boy.__proto__ === people); // true
 
    // 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
    console.log(boy.prototype.__proto__ === people.prototype); // true
</script>
相关推荐
mCell8 分钟前
JavaScript 的多线程能力:Worker
前端·javascript·浏览器
weixin_437830942 小时前
使用冰狐智能辅助实现图形列表自动点击:OCR与HID技术详解
开发语言·javascript·ocr
汇能感知2 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun2 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao2 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾3 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
gnip3 小时前
JavaScript事件流
前端·javascript
小菜全3 小时前
基于若依框架Vue+TS导出PDF文件的方法
javascript·vue.js·前端框架·json
wow_DG3 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(一):响应式原理
前端·javascript·vue.js
weixin_456904273 小时前
UserManagement.vue和Profile.vue详细解释
前端·javascript·vue.js