【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>
相关推荐
Nu11PointerException1 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
亦枫Leonlew3 小时前
三维测量与建模笔记 - 3.3 张正友标定法
笔记·相机标定·三维重建·张正友标定法
考试宝3 小时前
国家宠物美容师职业技能等级评价(高级)理论考试题
经验分享·笔记·职场和发展·学习方法·业界资讯·宠物
cs_dn_Jie3 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿4 小时前
webWorker基本用法
前端·javascript·vue.js
清灵xmf5 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据5 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
黑叶白树5 小时前
简单的签到程序 python笔记
笔记·python
qq_390161775 小时前
防抖函数--应用场景及示例
前端·javascript