zoukankan      html  css  js  c++  java
  • 面向对象原型的七种方法详解(前)

    1. 工厂模式
    2. 构造函数模式
    3. 原型模式
    4. 混合构造函数和原型模式
    5. 动态原型模式
    6. 寄生构造函数模式
    7. 稳妥构造函数模式

    普通模式
    var obj=new Object();
       obj.name="罗桂鑫";
       obj.age=18;
       obj.run=function(){
       return this.name+"+"+this.age+"+"+"100";
       }
       alert(obj.run());

    一。工厂模式

    为了解决多个类似对象声明的问题,我们可以使用一种叫做工厂模式的方法,这种方法就是为了解决实例化对象产生大量重复的问题。

    function show(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.run=function(){
    return this.name+"+"+this.age+"+"+"100";
    };
    return obj;
    };
    var box1=show("罗桂鑫",18);
    var box2=show("罗桂鑫",20);
    alert(box1.run());
    alert(box2.run());
    alert(box1.instanceof Object);
    alert(box1.instanceof Object);//不管怎样,他们都是Object类型,返回都是true.

    问题:工厂模式解决了重复实例化的问题,但还有一个问题,就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。

    二。构造函数模型

    使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,但问题
    是,这里并没有 new Object(),为什么可以实例化 Box(),这个是哪里来的呢?
    使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
    1.构造函数方法没有显示的创建对象(new Object());
    2.直接将属性和方法赋值给 this 对象;
    3.没有 renturn 语句。
    构造函数的方法有一些规范:
    1.函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和
    普通函数);
    2.通过构造函数创建对象,必须使用 new 运算符。

    function Show(name,age){
    this.name=name;
    this.age=age;
    this.run=function(){
    return this.name+"+"+this.age+"+"+"100";
    };
    }
    function Show2(name,age){
    this.name=name;
    this.age=age;
    this.run=function(){
    return this.name+"+"+this.age+"+"+"100";
    };
    }
    var box1=new Show("罗桂鑫",18);//实例化
    var box2=new Show2("罗桂鑫",18);//实例化

    var box3=new Show2("罗桂鑫",18);//实例化
    // alert(box1.run());
    // alert(box2.run());
    // alert(box1 instanceof Show);//true
    // alert(box3 instanceof Show);//false 因为box2是Show2对象的引用,所以返回false
    // alert(box1.run()==box2.run());//true //值相同
    // alert(box1.run==box2.run); //false //引用地址不同

    function Show(name,age){
    this.name=name;
    this.age=age;
    this.run=run;
    };
    function run(){ //把构造函数内部的方法通过全局来实现引用地址一致,但是外部也可以调用。所以不推荐
    return this.name+"+"+this.age+"+"+"100";
    };
    var box1=new Show("罗桂鑫",18);//实例化
    var box2=new Show("罗桂鑫",18);//实例化
    alert(box1.run==box2.run);//true

    -----------对象冒充的两种方法
    function Show(name,age){
    this.name=name;
    this.age=age;
    this.run=function(){
    return this.name+this.age+"+"+"100";
    };
    }
    var box1=new Show("罗桂鑫",18);//实例化
    alert(box1.run());
    var obj=new Object();
    Show.call(obj,"lee",100); //使用call对象冒充
    alert(obj.run());
    Show.apply(obj,["tin",100]); //使用apply对象冒充
    alert(obj.run());

    三。原型模型

    创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是
    包含可以由特定类型的所有实例共享的属性和方法。逻辑上可以这么理解:prototype 通过
    调用构造函数而创建的那个对象的原型对象。使用原型的好处可以让所有对象实例共享它所
    包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息
    添加到原型中。

    原型模式的执行流程:
    1.先查找构造函数实例里的属性或方法,如果有,立刻返回,实例属性不会共享;
    2.如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回;

    function box(){
    }
    box.prototype.name="罗桂鑫";
    box.prototype.age=18;
    box.prototype.run=function(){
    return this.name+"+"+this.age+"+"+"100";
    };
    var box1=new box();
    var box2=new box();
    alert(box1.run());
    alert(box1.run==box2.run);//true
    //如果是实例方法,不同的 实例化,他们的方法地址是不一样的
    //如果是原型方法,地址是共享的

    // 判断一个对象是否指向了该构造函数的原型对象,可以使用 isPrototypeOf()方法来测试。
    alert(box.prototype.isPrototypeOf(box1)); //只要实例化对象,即都会指向
    alert(box1.hasOwnProperty("name"));//判断实例中是否存在制定属性
    alert("name" in box1); //无论该属性存在于实例中还是原型中。只要存在就返回true

    function isProperty(object, property) { //判断原型中是否存在属性
    return !object.hasOwnProperty(property) && (property in object);
    }
    alert(isProperty(box1, 'name'));

    字面量创建的方式使用 constructor 属性不会指向实例,而会指向 Object,构造函数创建
    的方式则相反。

    function Box(){}
    //使用字面量的方式创建原型对象,这里{}就是对象,是Object,new Object就相当于{}
    Box.prototype={
    constructor:Box, //强制指向Box
    name:'lee',
    age:100,
    run:function(){
    return this.name+this.age+"运行中...";
    }
    };

    //重写了原型对象
    Box.prototype={
    age:200 //这里不会保留之前原型的任何信息了,把原来的原型对象和构造函数对象实例之前的关系切断了
    };
    var box=new Box();
    alert(box.name);
    alert(box.constructor==Box); //true

    原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺
    点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。

  • 相关阅读:
    微服务架构有哪些优势?
    Java 线程数过多会造成什么异常?
    Java 死锁以及如何避免?
    抽象的(abstract)方法是否可同时是静态的(static), 是否可同时是本地方法(native),是否可同时被 synchronized 修饰?
    内部类可以引用它的包含类(外部类)的成员吗?有没有 什么限制?
    CSS选取第几个标签元素:nth-child、first-child、last-child
    数据库约束
    DQL查询语句
    网络编程(客户端,服务端文件上传下载)
    缓冲流,转换流
  • 原文地址:https://www.cnblogs.com/luoguixin/p/6142149.html
Copyright © 2011-2022 走看看