美文网首页首页投稿(暂停使用,暂停投稿)
javaScript:3天理解面向对象(1)

javaScript:3天理解面向对象(1)

作者: 小飞蚁 | 来源:发表于2017-09-09 14:48 被阅读0次

    面向对象:

    什么是对象?
      - 对象就是对事物的描述,简单来说世界上的任何物质都是对象(万物皆对象)-日月星辰、花草树木、飞禽走兽;  
    
    什么是面向对象?
      - 把数据以及数据的操作方法放到一起,形成相互依存的整体,然后把这些 数据中具有相同特征的抽取出来,形成类。通过封装隐藏内部细节,通过继承实现类的特化,  通过多态实现基于对象类型的动态分派;<Milo Yi在知乎上的回答>
    
    以人为例进行对象的描述(对象的描述就是:属性+方法):
      -人的特征:
      -属性:身高,体重,家庭背景;
      -方法:吃饭,唱歌,跳舞,跑步,画画,下棋。。。。
      -(上面的已人为例的例子,是不是只要是个人都会做的事情,当然咱先不管他做的好还是不好。)
    
    那么具体的个人呢?
      1.阿大
      -属性:身高150cm,体重75kg,爸妈是很有钱的人;
      -方法:唱歌唱的很好,跑步跑的很快;
      2.阿二:
      -属性:身高170cm,体重80kg,爸妈是农民;
      -方法:会跳街舞,下棋拿过奖;
      (从上面来说,人的特征是不是来说,是一个共性,只要是个人就会有的特征和行为,像一个模板。阿大和阿二是个体的,他们之间有不同的差异);
    
    怎么用代码来表现出来呢?
    function Person(height,weight,homeBack){
          this.height=height;
          this.weight=weight;
          this.homeBack=homeBack;
          this.showSigne=function(){
                console.log(this.name+'我喜欢唱歌');
      }
         this.showDance=function(){
              console.log(this.name+'我喜欢跳舞');
    }
    }
    var p1=new Person('150cm','75kg','富豪');
    console.log(p1.height);
    console.log(p1.weight);
    p1.showSigne();
    var p2=new Person("170cm","80kg","农民");
    console.log(p2.height);
    console.log(p2.weight);
    p2.showDance();
    -从上面可以看出Person这个函数,像一个模板似的,把人的所有的属性和行为全部记录下来(我们把它称为构造函数);p1,p2是Person这个函数的具体个例(我们把它称为实例对象);
    
    构造函数以及构造函数的返回值
    -构造函数(模板)是抽象的;构造函数的作用就是实例化,产生一个对象;
    -构造函数的返回值是this,如果把构造函数的返回值设为普通的数据类型,那么它的返回值还是this,如果把构造函数的返回值设置为对象,那么它的返回值是对象;
    function Tag(name,age){
        this.name=name;
        this.age=age;
        return "aa";
    }
    var tag=new Tag("张三","19");
    console.log(tag);    
    

    输出结果:

    输出结果
    再来看一个案例:
      function Tag(name,age){    
                this.name=name;
                this.age=age;
                return {
                    name:'李四'
                };
            }
      var tag=new Tag("张三","19");
      console.log(tag); 
    

    输出结果:


    这就充分说明,构造函数的返回值,如果是简单的数据类型那么返回值是this,如果是对象类型那么返回自己设置的数值<如果普通函数没有设置返回值,那么返回的是undefind>;
    #######实例对象的产生方式

    1.字面量

    var str="qq";
    var num=222;
    var boolean=true;
    var obj={};
    var arr=[1,2,34,5];
    var arr=new Arry(1,2,3);
    var fn=new Function();
    var date=new Date();
    var reg=new RegExp();
    

    字面量创建对象案例:

    var p1={};
     p1.name="张三";
     p1.age=15;
     p1.showName=function(){
          console.log(this.name+"helloWord");
    }
    var p2={};
    p2.name="李四";
    p2.age=16;
    p2.showName=function(){
        console.log(this.name+"helloWord");
    }
    (发现通过字面量创建出来的实例对象,代码冗余度比较高,不可取。)
    

    2.通过构造函数实例化对象

    系统中提供的构造函数
    var obj=new Object();
    var arr=new Array();
    var date=new Date();
    var reg=new RegExp();
    var str=new String();
    var num=new Number();
    var boole=new Boolean();
    var fn=new Function();

    function Person(){
        this.name=name;
        this.age=age;
        this.showName=function(){
            console.log(this.name+"helloWord");
     }
    }
    var p1=new Person("张三",16);
    var p2=new Person("赵四",18);
    (通过构造函数实例化出来的对象代码简洁,后期可维护性更高);
     (实例对象包含一系列键值对,键是字符串,值可以是任意的数据类型);
     看个案例:
      var obj={};
      obj.list={
          ids:[{
              name:"张三",
              age:15,
              scoa:[1,2,34,12,7]
    }]        
    };
    (这个案例充分说明了实例对象的的内容都是键值对,键是字符串,值可以是任意的数据类型)
    
    作业:以老虎为例创建一个构造函数并实例化出来两只老虎

    答案:

        function Tag (name,color,hobby) {
                this.name=name;
                this.color=color;
                this.hobby=hobby;
                this.showName=function  () {
                    console.log(this.name+":我喜欢踢球!")
                }
                this.showAge=function  () {
                    console.log(this.name+":我喜欢跑步!")
                }
            }  
            var tag1=new Tag("小白","白色","跳舞");
            var tag2=new Tag("小黄","黄色","画画");
    
    实例对象的访问方式

    用.访问
    tag1.name;
    tag1.showName();
    用[]访问
    tag1[''name'];
    tag1'showName';

    基本类型和引用类型
    console.log(tag1.showName==tag2.showName)//false;
    console.log(tag1.showAge===tag2.showAge)//false;
    (为什么会不相等呢?)
    因为引用类型比较的是内存地址;
    

    这是一张引用类型的内存图:


    从图中可以知道,内存分为栈空间和堆空间;栈空间存储变量名然后返回一个内存地址;

    解析:tag1和tag2是Tag的两个实例,从图中可以看出内存的分布状态,线1和线2分别指向堆内存中开辟的空间。构造函数中的方法也在堆内存中开辟出两个空间。那假如这样来说假如构造函数有100个实例对象,那么就要在堆内存中开辟100个方法空间,从某种意义上说,这是不是浪费了内存空间?我们该怎么去解决这个问题呢?

    prototype

    我们通过prototype来解决空间冗余的问题;

    每个构造函数都有一个prototype属性,这个属性默认 是Object的实例(或者{}的实例),prototype有两个属性proto和constructor,prototype中的属性和方法被实例对象所共享;

    案例:

        function Tag (name,color,hobby) {
                this.name=name;
                this.color=color;
                this.hobby=hobby;
            }
            Tag.prototype.showName=function  () {
                console.log(this.name+":helloWord!")
            }
            var tag1=new Tag("小白","白色","跳舞");
            var tag2=new Tag("小黄","黄色","画画");
            console.log(tag1.showName==tag2.showName);
            console.log(tag1.showName===tag2.showName);
    

    结果为:


    这是面向对象的最小案例:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            div{
                background: red;
                border: 1px solid #ccc;
                width: 100px;
                height: 100px;
            }
        </style>
    </head>
    <body>
        <button id="btn">点击</button>
        <div id="div1"></div>
        <script type="text/javascript">
            function Foo (div1,btn) {
                this.div1=document.getElementById(div1);
                this.btn=document.getElementById(btn);
            }   
            Foo.prototype.innit=function () {
                var _this=this;
                this.btn.onclick=function  () {
                    _this.changeStyle(this);
                }
            }
            Foo.prototype.changeStyle=function  (that) {
                this.div1.style.width="200px";
                this.div1.style.heigth="200px";
                this.div1.style.background='yellow';
                that.style.background='red';
            }
            var c1=new Foo('div1','btn');
            c1.innit();
        </script>
    </body>
    </html>

    相关文章

      网友评论

        本文标题:javaScript:3天理解面向对象(1)

        本文链接:https://www.haomeiwen.com/subject/gbaojxtx.html