Javascript面向对象与原型

时间:2022-05-22 19:48:01
var box = new Object();//创建对象
box.name = 'Lee';//添加属性
box.age = 100;
box.run = function(){//创建方法
	
	return this.name + this.age +'运行中.....'
}
alert(box.run());



//工厂模式
function createObject(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('Jack', 200);
alert(box1.run());
alert(box2.run());

//构造函数模式
function Box(name, age){
	this.name = name;
	this.age = age;
	this.run = function(){
		return this.name + this.age + '运行中...';
	};
}
//1.构造函数没有new Object,但它后台会自动 var obj = new Object()
//2.this就相当于obj
//3.构造函数不需要返回对象引用,它是后台自动返回的

var box1 = new Box('Lee', 100);
var box2 = new Box('Jack', 200);
alert(box1.run());
alert(box2.run());

alert(box1 instanceof Box);

var o = new Object();
Box.call(o, 'Lee',100);    //对象冒充
alert(o.run());             //返回Lee100运行中...

alert(box1.name == box2.name);       //true
alert(box1.age == box2.age);           //true
alert(box1.run()== box2.run());        //true 这里比较的是方法的值 

alert(box1.run== box2.run);             //false 这里比较的是引用地址

---------------------------------------------------------------------

//构造函数模式
function Box(name, age){
	this.name = name; //实例属性
	this.age = age;
	this.run = run;   //实例方法
}

function run(){
		return this.name + this.age + '运行中...';
	};
var box1 = new Box('Lee', 100);
var box2 = new Box('Lee', 100);

alert(box1.run== box2.run);  //true  把构造函数内部的方法通过全局来实现引用地址一致

原型

//原型
function Box(){
}
Box.prototype.name='Lee';                        //原型属性
Box.prototype.age=100;
Box.prototype.run = function(){                  //原型方法
	return this.name + this.age + '运行中...';
};
var box1 = new Box();   
var box2 = new Box()                          
alert(box1.run());

//如果是实例方法,不同的实例化,他们的方法地址是不一样的,是唯一的
//如果是原型方法,那么他们的地址是共享的,大家都是一样
function Box(){}
Box.prototype = {                      //使用字面量方式创建原型对象
	name : 'Lee',
	age : 100,
	run:function(){
		return this.name + this.age + '运行中...';
	}
};
var box = new Box();
alert(box.run());

alert(box1.run==box2.run);

//使用原型扩展内置引用类型的方法
String.prototype.addstring = function(){
	return this + '被添加了';
}
var box =  'Lee';
alert(box.addstring());

//原型的缺点:共享
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);  //在第一个实例修改后引用类型,保持了共享

 //组合构造函数+原型模式,这种混合模式很好的解决了传参和引用共享的大难题,是创建对象比较好的方法
 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.run());
alert(box1.family);
box1.family.push('弟弟');
alert(box1.family);

var box2 = new Box('Jack',200);
alert(box2.run());
alert(box2.family);

//动态原型模式
//可以将原型封装到构造函数里
function Box(name, age){                  
	 this.name = name;
	 this.age = age;
	 this.family = ['哥哥','姐姐','妹妹'];
	 
	 if(typeof this.run != 'function'){   //判断this.run是否存在
		 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){
	var obj = new Object();
	obj.name = name;
	obj.age = age;
	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 Box(name,age){
	var obj = new Object();
	obj.name = name;
	obj.age = age;
	obj.run = function(){
		return name + age + '运行中...'
	};
	return obj;
}

var box1 = Box('Lee', 100);
alert(box1.run());
 var box2 = Box('Jack',200);
alert(box2.run());

继承

//继承 通过原型链实现

	function Box(){
		this.name = 'Lee';
	}
	function Desk(){
		this.age = 100;
	}
	function Table(){
		this.level = 'AAAAA';
	}
	
	//通过原型链继承,超类型实例化后的对象实例,赋值给子类型的原型属性
	//new Box()会将Box构造里面的信息和原型里的信息都交给Desk
	Desk.prototype = new Box();
	Table.prototype = new Desk();
	var desk = new Desk();
	alert(desk.age);
	
	var table = new Table();
	alert(table.age);
	alert(table.name);
=-------------------------------

	function Box(){
		//this.name = 'Lee';
	}
	Box.prototype.name = 'Jack';
	function Desk(){
		this.age = 100;
	}

	Desk.prototype = new Box(); //通过原型链继承

	var desk = new Desk();
	alert(desk.name); //就近原则,实例里有,就返回,没有就去查找原型

-----------------------------------------------

//使用对象冒充继承
function Box(name,age){
	this.name= name;
	this.age = age;
	this.family = ['哥哥','姐姐','妹妹'];//引用类型,放在构造里就不会被共享
}
function Desk(name, age){
	 Box.call(this, name, age); //对象冒充,对象冒充只能继承构造里的信息
}
var desk = new Desk('Lee', 100);
alert(desk.name);
alert(desk.family);	

// 组合继承
function Box(name,age){
	this.name= name;
	this.age = age;
	this.family = ['哥哥','姐姐','妹妹'];
}
Box.prototype.run = function(){
	return this.name + this.age + '运行中...';
}
//构造函数里的方法,放在构造里,每次实例化,都会分配一个内存地址,浪费,所以最好放在原型里,
function Desk(name, age){
	 Box.call(this, name, age); //对象冒充
}

Desk.prototype = new Box();		//原型链继承
var desk = new Desk('Lee', 100);
alert(desk.run());

//原型式继承
//临时中转函数
function obj(o){        //o表示将要传递进入的一个对象
	function F(){}		//F构造是一个临时新建的对象,用来存储传递过来的对象
	F.prototype = o;//将o对象实例赋值给F构造的原型对象
	return new F();//最后返回这个得到传递过来对象的对象实例
}
var box = {
	name:'Lee',
	age:100,
	family:['哥哥','姐姐','妹妹']
};

var box1 = obj(box);//box1就等于new F()
alert(box1.name);
box1.family.push('弟弟');
alert(box1.family);

var box2 = obj(box);
alert(box2.family);   //引用类型共享了

//寄生式继承= 原型式+工厂模式

function obj(o){        
	function F(){}	
	F.prototype = o;
	return new F();
}
//寄生函数
function create(o){
	var f = obj(o);
	f.run = function(){
		return this.name + '方法';
	}
	return f;
}
var box = {
	name:'Lee',
	age:100,
	family:['哥哥','姐姐','妹妹']
};

var box1 = create(box);
alert(box1.name);
alert(box1.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()
var desk = new Desk('Lee', 100);
alert(desk.run());