Js基本知识点以及相关内容的测试------面向对象

       万物皆对象

        将一个班的所有同学都比作一个普通对象,现在想对这个班学生的信息进行保存,操作如下:

         1)声明学生对象,每一个学生对象都具有一些相同的属性,如果每一个学生都一个一个地声明,会很复杂。解决方法就是将相同的部分进行封装。(工厂模式)

            var stu1={          //声明一个学生对象,包含name等属性
            name:'lisi',
            age:20,
            gender:'men',
            say:function( ){ }
            ...
        }
        var stu={                  //声明一个学生对象,包含name等属性
            name:'tom',
            age:20,
            gender:'women',
            say:function( ){ }
            ....
        }

1.工厂模式

          function setStudent(name,age,gender){                       //声明一个函数包含公共部分的属性,属性名都有

                    var obj=new Object( );                            //创建一个空对象

                    obj.name=name;                                    //往空对象里填属性

                    obj.age=age;

                    obj.gender=gender;

                    obj.say=function( ){                                  //声明一个公有的属性,属性值也相同       //在此声明say时是声明给了obj,obj是上面创建空对象创建来的,调用一次setStudent,创建一个新的对象,形成一个新的空间,stu1在调用setStudent和stu2在调用setStudent时,里面obj生成的内存空间不是一个,里面的say方法也不是一个,不在一个内存空间中引用地址也就不是一个了

                                  alert("hello,say---------");

                    }

                    return obj;                         //返回对象包括它的内容

           }

          var stu1=setStudents("lisi",20,"men");                 //调用函数,将实参传给形参,声明一个变量接收调用函数得到的返回值

          var stu2=setStudents("tom",23,"men");

          var stu3=setStudents("terry",25,"men");

          console.log(stu1.constructor);               //打印stu1和stu2的构造者,二者都被function Object( )构造,因为存储学生信息的空间是通过new Object( )得到的。

          console.log(stu2.constructor);

          stu1.say( );                  //调用say( )

          stu2.say( );

          console.log(stu1.say==stu2.say);             //say是引用数据类型,进行==比较,比较的是引用地址,引用地址在声明那儿找

     相较于上面的一个一个变量的声明,工厂模式大大的减少了代码,即使以后需要声明的对象多也比上面一个一个声明少,对象写得越多,越能体现封装的好处。

 考虑:stu1是否等于stu2?       stu1.say( )是否等于stu2.say( )?

        console.log(stu1==stu2);        //不等于

        console.log(stu1.say==stu2.say);        //不等于

如下图为内存分析图:

 工厂模式的优点:简化代码的操作(封装)

缺点:1.对象不能细分  2.公有属性和方法浪费内存

2.构造函数模式(解决工厂模式的对象不能细分问题)

                  function say(){                 //公有部分放在外面

                        alert();

                  }

           function Student(name,age,gender){           //声明构造函数Student       //形参将值赋给谁需要调用一个对象出来

                 //new Object( )  不需要

                  this.name=name;                       //不能new Object( ),不然类型仍为object类型,所以用this关键字

                  this.age=age;                            //this指向谁,this被属于Student一部分,它被new调用,new为堆区中的新的内存空间,相当于在新的内存空间添加属性

                  this.gender=gender;

                  this.say=say;

                  /*this.say=function(){                 //存放公有属性,属性名+属性值都相同的部分

                        alert();

                  }*/

                  // return       不需要

            }

           var stu1=new Student("lisi",20,"men");          //调用构造函数Student,将实参传给形参,声明变量stu1接收Student的返回值

           var stu2=new Student("tom",23,"men");

          console.log(stu1.constructor);               //Student

           console.log(stu1==stu2)             //反回false,因为stu1和stu2都是new Student,new意味着新开辟一个空间,两者的所属空间不同

           stu1.say( );

           stu2.say( );

           console.log(stu1.say==stu2.say);           //返回值false,原理同工厂模式

优点:在工厂模式的基础上解决了对象细分问题

缺点:内存问题没有彻底解决

有可能出现stu1.say==stu2.say的情况如下图:将say函数写在构造函数和原型对象和实例对象的外面,可暂时解决内存空间问题

公有属性放在外面会比较乱,放在原型对象中合适,原型对象就是用来存放静态属性和方法的。

3.原型对象模式

      function Student( name,age,gender){

              this.name=name;

              this.age=age;

              this.gender=gender;

      }

      /*Student.prototype.say=function( ){}              //在原型对象中声明函数say

      Student.prototype.run=function( ){}*/              //想简化操作,不要这两步,直接用下行的{ },但是stu1和stu2构造者仍为Student,分析如下图2

      Student.prototype={                              //为何此时say和run不能调用,分析如下图1       ,{ }相当于new Object(隐晦)

           constructor:Student,                    //{ }(Object实例)含有constructor属性,将它的构造者强制指向Student

           enjoy:function( ){},

           work:function( ){}

     }

      var stu1=new Student("lisi",20,"men");            //调用Student函数,将实参传给形参,将函数返回值赋给stu1

      var stu2=new Student("tom",23,"men");

      stu1.say( );            //say在原型对象中,stu1和stu2都可以调用,且只有原型对象和实例对象可调用,stu1.say==stu2.say返回true

      stu2.say( );

                                                 图1

 

                                                  图2

4.继承

      让子类的原型指向父类的实例

      父类实例对象的constructor指向子类的构造函数

      function Rich(name,age,gender){

             this.name=name;

             this.age=age;

             this.gender=gender;

      }  

      Rich.prototype.money=["card1","card2","card3"];

      Rich.prototype.enjoy=function( ){

             alert("enjoy");

      }

      function Poor(name,age,gender,color){

              Rich.call(,this,name,age,gender);               //不加.call指向window,加.call指向this

              /*this.name=name;

              this.age=age;

              this.gender=gender;*/

              this.color=color;

      }

      /*Poor.prototype=Rich.prototype;          //这两步操作的过程

      Rich.prototype.constructor=Poor;    */      //分析图如下图1

      Poor.prototype=new Rich( );             //子类的原型指向父类的实列

      Poor.prototype.constructor=Poor;

      Poor.prototype.work=function( ){

              alert("work-------------");

      }

      var r1=new Rich("lisi",23,"men");

      var p1=new Poor("tom",20,"men","black");

    

                                                                 图1

    

                                                                 图2

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值