• JS学习专辑(7)"类"的创建和继承


    其实在JS中是没有类这个概念的,它没有像Class那样的专门定义的类,但我们一般可以通过对对象创建的模拟把它模拟成类。

    书上介绍了几种创建类的方式,在这里:

    1.工厂方式:这个方式在函数内部定义对象,并定义各种属性,最后返回对象。一般如果用这个的话我们把属性方法定义在函数外面,这样就可以避免重复创建该方法。

    function Student1(name,age){
        var obj=new Object();
        obj.name=name;
        obj.age=age;
        obj.f=f;
        
        return obj;
    }
    var f=function(){
        return (this.name+" "+this.age);
    }
    var student1=Student1("jk","12");
    console.log(student1.name+" "+student1.age+" "+student1.f());    //jk 12 jk 12
    if(student1 instanceof Student1){console.log("Y")}else{console.log("N")}    //N
    View Code

    只是上面这种方式无法进行对对象的类型的识别的,也就是说无法通过instanceof方法判断它属于那个类。

    2.构造函数方式:这个方式使用构造函数创建对象,不用在函数内部创建,而使用this指代,不用return。同上一样,如果用这个就要把方法定义在外面。

    function Student2(name,age){
        this.name=name;
        this.age=age;
        this.f=f;
    }
    var f=function(){
        return (this.name+" "+this.age);
    }
    var student2=new Student2("jk","12");
    console.log(student2.name+" "+student2.age+" "+student2.f());    //jk 12 jk 12
    if(student2 instanceof Student2){console.log("Y")}else{console.log("N")}    //Y
    View Code

    3.原型方式:在函数中不对属性进行定义,然后利用prototype的属性进行属性定义。

    function Student3(name,age){
        
    }
    Student3.prototype={
        name:null,
        age:null,
        f:function(){
            return this.name+" "+this.age;
        }
    };
    var student3=new Student3;
    student3.name="jk";
    student3.age="12";
    console.log(student3.name+" "+student3.age+" "+student3.f());    //jk 12 jk 12
    View Code

    只是单单用原型方式的话不是很好,因为当这个类有一个引用属性时,改变一个对象的这个属性也会改变其他对象得属性。比如一个Array再push进去东西的话,其他的对象属性也会更改。

    4.混合的构造函数和原型模式(都推荐使用的是这个):将所有的不是方法的属性定义在函数中,将所有方法属性利用prototype定义在函数外面:

    function Student4(name,age){
        this.name=name;
        this.age=age;
    }
    Student4.prototype.f=function(){
        return this.name+" "+this.age;
    }
    var student4=new Student4("jk",12);
    console.log(student4.name+" "+student4.age+" "+student4.f());    ////jk 12 jk 12
    View Code

    这个是使用率最高的一种方式,也没有上面那些缺点。

    5.动态原型方式(这个也是常用的):这个和上面那个是差不多的,都是在不是方法的属性定义在函数中,所有方法利用prototype定义。唯一的区别是赋予对象方法的位置。

    function Student5(name,age){
        this.name=name;
        this.age=age;
        if(typeof Student5.f=="undefined"){
            Student5.prototype.f=function(){
                return this.name+" "+this.age;
            }
            Student5.f=true;
        }
    }
    
    var student5=new Student5("jk",12);
    console.log(student5.name+" "+student5.age+" "+student5.f());    //jk 12 jk 12
    View Code

    上面一些就是类的创建的方法,然后类的继承的话最简单的是通过利用共享prototype实现继承,先看下例子:

    function Student6(name,age){
        this.name=name;
        this.age=age;
    }
    Student6.prototype.f1=function(){
        return this.name;
    }
    Student6.prototype.f2=function(){
        return this.age;
    }
    function Candle(name,age,islight){
        this.name=name;
        this.age=age;
        this.islight=islight;
    }
    Candle.prototype=Student6.prototype;    //也可以这样Candle.prototype=new Student6();
    Candle.prototype.f3=function(){
        return this.islight;
    }
    var student6=new Student6("jk",12);
    console.log(student6.f1()+" "+student6.f2());    //jk 12
    var candle=new Candle("jk",12,"no");
    console.log(candle.f1()+" "+candle.f2()+" "+candle.f3());    //jk 12 no
    console.log(candle instanceof Student6);    //true
    console.log(candle instanceof Candle);        //true
    View Code

    上面的例子中第二个类继承了第一个类的f1和f2的方法,这是通过拷贝第一个类的prototype到第二个来实现的。然后用instanceof来判断了下对象是否是这两个类的实例是OK的。因为这个是用共享prototype的方法来实现定义的,是对同一个对象的引用,所以惟一的约束是不允许类成员的覆盖定义。

    上面那种方法在不要求严格的情况下,这样的继承是比较简单方便的。但是毕竟如果成员的重新定义都会互相有影响,所以还有一种方法是通过反射机制和prototype实现继承,思路和上面那个差不多,但利用for(…in…)语句枚举出所有基类prototype的成员,并将其赋值给子类的prototype对象。下面是例子:

    function Student7(name,age){
        this.name=name;
        this.age=age;
    }
    Student7.prototype.f1=function(){
        return this.name;
    }
    Student7.prototype.f2=function(){
        return this.age;
    }
    function Candle(name,age,islight){
        this.name=name;
        this.age=age;
        this.islight=islight;
    }
    //让Candle继承于Student7
    for(var p in Student7){
        Candle.prototype[p]=Student7.prototype[p];
    }
    Candle.prototype.f1=function(){        //覆盖第一个类的f1方法
        return this.age;    
    }
    Candle.prototype.f2=function(){        //覆盖第一个类的f2方法
        return this.name;
    }
    Candle.prototype.f3=function(){
        return this.islight;
    }
    var student7=new Student7("jk",12);
    console.log(student7.f1()+" "+student7.f2());    //jk 12
    var candle=new Candle("jk",12,"no");
    console.log(candle.f1()+" "+candle.f2()+" "+candle.f3());    //12 jk no
    View Code

    OK,上面的那些就是关于js类的创建和继承,如有新东西可以继续补充~

     

  • 相关阅读:
    JSON, String,Map,实体对象之间的转换
    使用mybatis-plus进行多表的条件查询(模糊查询)
    Netty整合WebSocket的使用
    Java流(stream)的使用
    mysql 查询当天、本周,本月,上一个月的数据......
    第七章 Centos7下Jira-8.16.1的安装
    第六章 JIRA基础介绍
    第五章 Confluence忘记密码
    第四章 Confluence服务的迁移
    第三章 Docker部署Confluence
  • 原文地址:https://www.cnblogs.com/socialdk/p/3095258.html
Copyright © 2020-2023  润新知