当前位置:首页 > javascript > 正文内容

面向对象构造函数模式

自由小鸟6年前 (2018-06-20)javascript2510

1,工厂模式

//工厂模式function createObiect(name,age){ 
    var obj=new Object();   //创建对象
     obj.name=name;          //添加属性
     obj.age=age;            
     obj.run=function(){     //添加对象方法
          return this.name+this.age+'运行中....'
     }; 
 return obj;             //返回对象引用
}
 var box1=createObject('Lee',100);
 var box2=createObject('jact',200);

alert(box1.run());
alert(box2.run());//问题识别不出来,搞不清谁到底是谁的对象

2,构造函数

fucntion Box(name,age){ 
    this.name=name; 
    this.age=age; 
    this.run=function(){  
        return this.name+this.age+'运行中';
    }
}
var box1=new Box('lee',100);
var box2=new Box('jack',200);
box1 instanceof Object//


使用构造函数和工厂模式的方法他们不同之处如下:

《1,构造函数方法没有显示的创建对象(New Object())

《2,直接将属性和方法赋值给this对象

《3,构造函数没有return 对象,是后台自动返回的

 

3,构造函数和普通函数的区别

构造函数调用必须使用new ,创建构造函数名首字母大写

4,对象冒充调用

fucntion Box(name,age){ 
    this.name=name; this.age=age; 
    this.run=function(){  
        return this.name+this.age+'运行中';
    }
}
var o=new Object();
Box.call(o,'lee',100);  //对象冒充,把Box的功能都拿给了o对象alert(o.run())
//对象冒充function Person(name,age){
    this.name = name;
    this.age = age;
    this.show = function(){
        console.log(this.name+", "+this.age);
    }
}
function Student(name,age){
    this.student = Person; //将Person类的构造函数赋值给
    this.studentthis.student(name,age); //js中实际上是通过对象冒充来实现继承的delete this.student; 
    //移除对Person的引用}
    var s = new Student("小明",17);
    s.show();
    var p = new Person("小花",18);
    p.show();// 小明, 17// 小花, 18

5,构造函数里的方法到底是基本类型还是引用类型

fucntion Box(name,age){ 
    this.name=name; 
    this.age=age; 
    this.run=function(){  
        //return this.name+this.age+'运行中';
      this.run=run;  
    }
}//注明全局name变量会存在问题,换个名字就可以,最好不要全局函数会
function run(){   //把构造函数内部的方法通过全局来实现引用地址一致
     return this.name+this.age+'运行中';
}
var box1=new Box('lee',100);       //实例化后地址为1var box2=new Box('lee',100);       
//实例化后地址为2//alert(box1.name==box2.name);     
//true
//alert(box1.age==box2.age);       
//true
//alert(box1.run()==box2.run());   //true 构造函数体内的方法的值是相当的
alert(box1.run==box2.run);         //false 因为他们比较的是引用地址

6,原型的缺点都是共享的,有些部分不希望共享

//原型的缺点//共享是优点也是缺点,如果box1和box2初始值不想一样的,所以这里是实现不了,都是共享的function Box(){}
Box.prototype={ constructor:Box, name:'lee', age:100, family:['哥哥','姐姐','妹妹'], run:function(){  return this.name+this.age+'运行中。。。'
 }  
}var box1=new Box();
alert(box1.family);    //哥哥,姐姐,妹妹box1.family.push('弟弟');
alert(box1.family);    //哥哥,姐姐,妹妹,弟弟var box2=new Box();
alert(box2.family);    //哥哥,姐姐,妹妹,弟弟  //共享了box1添加后的引用的原型

7,组合构造函数+原型模式

//组合构造函数+原型模式function Box(name,age){        //需要独立的用构造函数
 this.name=name; 
 this.age=age; 
 this.family:['哥哥','姐姐','妹妹'];
}
Box.prototype={                //保持共享的用原型
 constructor:Box,
 run:function(){  
     return this.name+this.age+'运行中。。。'
 }
}var box1=new Box('lee',100);
alert(box1.family);            //哥哥,姐姐,妹妹box.family.push('弟弟');
alert(box1.family);            //哥哥,姐姐,妹妹,弟弟var box2=new Box('jack',200);
alert(box2.family)             //哥哥,姐姐,妹妹

8,动态原型模式

//动态原型模式//可以将原型封装到构造函数里
function Box(name,age){ 
this.name=name; 
this.age=age; 
this.family=['可可','姐姐','妹妹']; 
 //这里的运行次数是几次呢?
 alert('原型初始化开始');
 Box.prototype.run=function(){   
     return this.name+this.age+'运行中。。。'
 }
 alert('原型初始化结束');
}
//原型的初始化,只要第一次初始化,就可以了,没必要每次构造函数实例化的时候都初始化var box1=new Box('lee',100);
alert(box1.run());var box2=new Box('jack',200);
alert(box2.run());

以下解决初始化多次的情况

function Box(name,age){ 
    this.name=name; 
    this.age=age; 
    this.family=['可可','姐姐','妹妹']; 
     if(typeof this.run !='function'){  
        //加上一个判断就可以解决多次的初始化问题
        Box.prototype.run=function(){    
            return this.name+this.age+'运行中。。。'
        }
     }
}
var box1=new Box('lee',100);
alert(box1.run());var box2=new Box('jack',200);
alert(box2.run());

9,寄生构造函数=工厂模式+构造函数

//寄生构造函数=工厂模式+构造函数function Box(name,age){ 
    var obj=new Object();
     obj.name=name;
     obj.run=function(){  
         return this.name+this.age+'运行中。。。'
     }; 
     return obj;
}
var box1=new Box('Lee',100);
alert(box1.run());
var box2=new Box('jack',200);
alert(box2.run());

级寄生组合继承

//临时中转函数function obj(o){ 
    function F(){};
    F.prototype=o; 
    return new F();
}
//寄生函数
function create(box,desk){ 
    var f=obj(box.prototype);
     f.constructor=desk;     //调整指针
     desk.prototype=f;
}
function Box(name,age){ 
    this.name=name; this.age=age;
}

Box.prototype.run=function(){ 
    return this.name+this.age+'运行中。。。'
}
function Desk(name,age){
     Box.call(this,name,age)
} 

//通过寄生组合继承来实现继承create(Box,Desk);   
//这句话用来替代Desk.prototype=new Box();


版权声明:本文由Web学习之路发布,如需转载请注明出处。

本文链接:https://webge.net/?id=10

“面向对象构造函数模式” 的相关文章

js原型链

js原型链

创建对象有几种方法:原型,构造函数,实例,原型链左边 实例对象  instanceof 构造函数  来判断是不是同一个引用原型用constructor 比instanceof来判断继承更严谨var o3=new M()o3 instanceof  M  &nb...

数组有哪些原生方法

赋值方法:pop 和 push   pop // 删除数组最后一个元素,返回被删除的元素push // 在数组尾部插入1-N个元素,返回操作后数组的lengthshift     //  删除数组第一个元素,返回被删除的元素uns...

正则的规则

正则的两个特点:懒惰:如果没有设置全局g的情况下,只匹配1次,这时候的lastIndex的值是0贪婪:...

数组去重

var a=[1,3,4,5,6,1,3,9,6]; //代码是去重后的 function arrfn(data){ let newObj={}; for(let i=0;i<data.length;i++...

js 深浅拷贝

对象浅拷贝Object.assign,也可以做到浅拷 slice let obj=[11,22,33,44,['aa','bb','cc']] let aaa=obj.slice(0); aaa[4][0]='ccc' c...