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.student
this.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); //实例化后地址为1
var 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();