zoukankan      html  css  js  c++  java
  • javascript面向对象与原型浅析2

    1、原型

    所有函数都包含prototype(原型)属性,该属性是对象,所有实例共享该原型内的属性和方法。

    //原型
    function Person () {       //构造函数
        // body...
    }
    Person.prototype.name='zhangsan';
    Person.prototype.age=26;
    Person.prototype.sayHello=function(){
        return this.name+this.age+"Hello World...";
    }
    var person1=new Person();
    person1.name='lisi';
    person1.age=53

    var person2=new Person();
    alert(person1.sayHello==person2.sayHello); //返回true,因为他们保存的是指向原型sayHello函数的指针地址(如下图右图所示),而构造函数的话此处返回false
    person1.email='lisi@163.com';  //增加属性
    alert(person1.hasOwnProperty("email"));//判断实例中是否存在指定属性
    delete person1.name;//删除实例属性是,使其访问原型里面改属性的值
    alert(person1.name);//zhangsan delete Person.prototype.name //删除原型属性 alert(person1.name);//undefined alert(person1.sayHello());*/

    ------------------------------------------也可用下面方法创建原型--------------------------------------------------------------
    function Person(){
    }
    Person.prototype={
        constructor:Person,//此处很重要,需要强制将constructor指向Person对象,默认不写的话,指向Object对象
    name:"zhangsan",
        age:26,
        sayHello:function(){
          return this.name+this.age +"Hello World.....";
        }
    }
    PS:为什么不写constructor会指向Object?因为Person.prototype={};这种写法其实创建了一个新对象,每创建一个函数,会同时创建它的prototype,自动获取constructor属性,不重写的话constructor指向Object,重写的话,指向Person。

    通过构造函数创建原型对象,不必再构造函数中定义对象信息,直接将信息添加到原型中 

     图解构造函数方式跟原型方式的不同:

    __proto__属性是实例指向原型对象的一个指针,作用指向构造函数的原型属性constructor,通过这两个属性访问原型里的属性和方法。

    原型模式的执行流程:

    1.先查找构造函数实例里的属性或方法,如果有,立刻返回;

    2.如果构造函数实例里面没有,则取原型对象里面查找,如果有,则返回;

    原型最大的优点是实例化的所有对象都能共享属性、方法,然而这也是其最大的缺点,每个实例化对象初始化的值都是一样的,不具有独立性,如下面一段代码:

    Person.prototype={
        constructor:Person,
        name:'zhangsan',
        age:50,
        family:['父亲','母亲','哥哥'],
        run:function(){
            return this.name+this.age+this.family;
        }
    }
    
    var person1=new Person();
    person1.name='wangwu';
    person1.age=60;
    person1.family.push('弟弟');//给person1的家庭成员加入‘弟弟’
    alert(person1.family);  // '父亲','母亲','哥哥','弟弟'
    var person2=new Person();
    person2.name='lisi';
    person2.age=100;
    alert(person2.family); // 这里也返回,'父亲','母亲','哥哥','弟弟',我们并不想让peron2的家庭成员里面也有弟弟,出现问题

     解决上面问题,我们需要用到下面一种方法:组合构造函数+原型模式

    2、组合构造函数+原型模式

    //组合构造函数+原型模式
    function Person(name,age){       //构造函数
        this.name=name;
        this.age=age;
        this.family=['父亲','母亲','哥哥'];
    }
    Person.prototype={               //原型
        constructor:Person,
        run:function(){
            return this.name+this.age+this.family;
        }
    }
    
    var person1=new Person('zhangsan',10);
    person1.family.push('弟弟');
    alert(person1.family);//'父亲','母亲','哥哥','弟弟'
    var person2=new Person('lisi',30);
    alert(person2.run());//'父亲','母亲','哥哥'

    PS:这种混合模式最大的好处是解决了传参和引用共享的问题,是创建对象比较好的方法,将需要共享的属性、方法放置在原型中,独立的属性、方法在构造函数中初始化。

  • 相关阅读:
    如何设置mysql数据库为只读
    华为S5300系列、S5700系列交换机无法修改密码问题分析
    一个form表单有两个按钮,分别提交到不同的页面
    在cmd/bat脚本中获取当前脚本文件所在目录
    以一个学生宿舍区为例,解析华为交换机AAA的配置
    mysql创建远程用户并授权
    锐捷交换机中的password与secret的区别
    机器学习基础及案例
    python所有基础
    win10找不到Hyper-V的解决方法
  • 原文地址:https://www.cnblogs.com/1017283242zhu/p/4519246.html
Copyright © 2011-2022 走看看