草庐IT

ES6 class类和继承

生命里那束光 2023-03-28 原文

一、class 类

1. 概述

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。

  • 通过 class 关键字,可以定义类。
  • 基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;

2. 知识点

  1. class 声明类;

  2. 类构造函数constructor 定义构造函数初始化;
    constructor关键字用于在类定义块内部创建类的构造函数。方法名constructor会告诉解释器在使用new操作符创建类的实例对象时,应该调用此方法。

  3. extends 继承父类;

  4. super 调用父级构造方法;

  5. static 定义静态方法和属性;

  6. 父类方法可以重写;

3. class类的构成

  • 类可以包含构造函数方法、原型方法、实例方法、获取函数、设置函数和静态方法。但是不必要的。空的类定义同样有效。默认情况下,类定义中的代码都是在严格模式下进行的。

代码实现:

<body>
    <script> 
        // 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); 
        
        
        // ES6写法 
        class Phone{ 
            // 构造方法,名字是固定的 
            constructor(brand,price) { 
            this.brand = brand; 
            this.price = price; 
            }
            
            // 打电话,方法必须使用该方式写
            call(){ 
                console.log("我可以打电话!"); 
            } 
        }
        let HuaWei = new Phone("华为",5999); 
        HuaWei.call(); 
        console.log(HuaWei); 
    </script> 
</body> 

运行结果:

实例化

使用new操作符实例化类时,相当于使用new调用其的构造函数。构造流程图如下:

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字。
  4. 开始执行构造函数内部的代码。(完成赋值等操作)
  5. 最后返回这个对象。

注意事项:

  • constructor构造函数不是必需的。不定义构造函数时相当于将构造函数定义为空函数。
  • 类构造函数与构造函数的区别:调用类的构造必须使用new操作符,而普通构造函数可以使用new,也可以不使用new。
  • 类可以认为是特殊的构造函数。typeof操作符检测一个类时,返回的结果为function。同时类中有[[Prototype]]属性,此属性中的constructor属性指向自身。与构造函数相同。

4. class静态成员

注意事项:

  1. ES5中,类函数对象和实例对象,属性(静态对象)互不相通

  2. 静态对象:在面向对象编程中,属于类函数对象,但不属于实例对象

  3. ES6中,静态对象用static定义

// ES6写法 
class Phone{ 
  // 静态属性 
  static name = "手机"; 
  static change(){ 
      console.log("我可以改变世界!"); 
  } 
}

二、ES5 组合继承(构造函数)

代码实现:

<body>
    <script> 
        // ES5构造函数继承 
        // 手机 
        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.game = function(){ 
            console.log("我可以玩游戏!"); 
        }

        const chuizi = new SmartPhone("锤子",2499,"黑色","5.5inch"); 
        console.log(chuizi); 
        chuizi.call(); 
        chuizi.photo(); 
        chuizi.game(); 
    </script> 
</body> 

运行结果:

三、ES6class类继承

代码实现:

<body>
    <script> 
        // ES6class类继承 
        class Phone{ 
            constructor(brand,price) { 
                this.brand = brand; 
                this.price = price; 
            }
            call(){ 
                console.log("我可以打电话!"); 
            } 
        }
        //SmartPhone类 继承 Phone类
        class SmartPhone extends Phone{ 
            // 构造函数 继承属性
            constructor(brand,price,color,size) { 
                super(brand,price); // 调用父类构造函数 
                this.color = color; 
                this.size = size; 
            }
            photo(){ 
                console.log("我可以拍照!"); 
            }
            game(){ 
                console.log("我可以玩游戏!"); 
            } 
        }
        const chuizi = new SmartPhone("小米",1999,"黑色","5.15inch"); 
        console.log(chuizi); 
        chuizi.call(); 
        chuizi.photo(); 
        chuizi.game(); 
    </script> 
</body>

运行结果:

四、子类对父类方法重写

代码实现:

<body>
    <script> 
        // ES6class类继承 
        class Phone{ 
            constructor(brand,price) { 
            this.brand = brand; 
            this.price = price; 
            }
            call(){ 
                console.log("我可以打电话!"); 
            } 
        }

        //定义子类
        class SmartPhone extends Phone{ 
            // 构造函数 
            constructor(brand,price,color,size) { 
                super(brand,price); // 调用父类的属性
                this.color = color; 
                this.size = size; 
            }
            // 子类对父类方法重写 
            // 直接写,直接覆盖 
            // 注意:子类无法调用父类同名方法 
            call(){ 
                console.log("我可以进行视频通话!"); 
            }
            photo(){ 
                console.log("我可以拍照!"); 
            }
            game(){ 
                console.log("我可以玩游戏!"); 
            } 
        }
        const chuizi = new SmartPhone("小米",1999,"黑色","5.15inch"); 
        console.log(chuizi);
        chuizi.call(); 
        chuizi.photo(); 
        chuizi.game(); 
    </script> 
</body>

运行结果:

五、class中的getter和setter设置

CLASS类里面可以设置getter和setter方法,

  • getter可以获取一些方法
  • setter可以设置一些方法

代码实现:

<body>
    <script> 
        // class中的getter和setter设置 
        class Phone{ 
            get price(){ 
                console.log("价格属性被读取了!"); 
                // 返回值 
                return 123; 
            }

            set price(value){ 
                console.log("价格属性被修改了!"); 
            } 
        }

        // 实例化对象 
        let s = new Phone(); 
        console.log(s.price); // 返回值 
        s.price = 2999; 
    </script> 
</body> 

运行结果:

有关ES6 class类和继承的更多相关文章

  1. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  2. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  3. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  4. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  5. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  6. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  7. ruby - 使用 Class.new 时访问外部范围 - 2

    是否有可能以某种方式访问​​Class.new范围内的a?a=5Class.new{defb;aend}.new.b#NameError:undefinedlocalvariableormethod`a'for#:0x007fa8b15e9af0>#:in`b' 最佳答案 即使@MarekLipka的回答是正确的——改变变量范围总是有风险的。这是可行的,因为每个block都带有创建它的上下文,因此您的局部变量a突然变得不那么局部了——它变成了一个“隐藏的”全局变量:a=5object=Class.new{define_method(

  8. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

  9. Ruby 最佳实践 : working with classes - 2

    参见下面的示例,我想最好使用第二种方法,但第一种也可以。哪种方法最好,使用另一种的后果是什么?classTestdefstartp"started"endtest=Test.newtest.startendclassTest2defstartp"started"endendtest2=Test2.newtest2.start 最佳答案 我肯定会说第二种变体更有意义。第一个不会导致错误,但对象实例化完全过时且毫无意义。外部变量在类的范围内不可见:var="string"classAvar=A.newendputsvar#=>strin

  10. ruby - 模块中的 instance_eval 与 class_eval - 2

    classFooincludeModule.new{class_eval"deflab;puts'm'end"}deflabsuperputs'c'endendFoo.new.lab#=>mc======================================================================classFooincludeModule.new{instance_eval"deflab;puts'm'end"}deflabsuperputs'c'endend注意这里我把class_eval改成了instance_evalFoo.new.labresc

随机推荐