1.面向对象的概念
其实面向对象是相对于面向过程而言,通俗来说就是创建对象,每个对象有自身的属性和方法,对象.属性 对象.方法 实际上这已经是一个面向对象的过程了,面向过程,是指执行一件事的流程,一步接着一步进行,举个例子来说,比如你去烧菜,面向过程的执行就是,你先要去买菜,然后你要去洗菜,然后烧菜等一系列具体的步骤,而对于面向对象而言,把你当做一个对象,买菜是一个对象,烧菜也是一个对象,你首先会传递消息,你要用菜,菜才就会出现,至于菜是怎么来的,买的还是偷得,那就不需要你知道.......等你洗好会菜会发送消息表明现在要烧菜,菜就会烧好,至于菜是如何烧的,过程如何,你也不需要知道,其实面向过程会细究每一步的执行过程,而面向对象不会细究。
----例子有点不恰当,面向对象的概念本身十分的抽象,只能慢慢体会
2 面向对象的设计模式
一.普通模式
普通模式比较繁琐,一个对象一个实例,
普通创建对象的方法,缺陷:
例如:
var people=new Object();
people.name="张三";
peoole.food="苹果";
people.eat=function(){
alert(this.name+"喜欢吃"+this.food)
}
people.eat())//张三喜欢吃苹果
var people1=new Object();
people1.name="李四";
peoole1.food="香蕉";
people1.eat=function(){
alert(this.name+"喜欢吃"+this.food)
}
people1.eat()//李四喜欢吃香蕉
//若有100个对象,则需要创建100次,不利于实际的开发
二 工厂模式
这种模式比较简单,其实就是在函数中创建一个对象,给对象添加属性及其属性值或属性方法然后在讲这个对象用return返回出来(return 是关键)
function create(name,food){
var people=new Object() //原材料;
people.name=nane
people.food=food
people.eat=function(){
alert(this.name+"喜欢吃"+this.food)
}//加工过程
return people;//产品
}
var people 1=create("小丸子",“海鲜”);//不用new关键字创建
var people2=create("小李","红烧肉");
people1.eat()
people2.eat()
//这种模式的缺点就是内存消耗大
people1==people2 //false,占用不同的内存空间
注意:上面提到一定工厂模式一定要有返回值
如果没有返回,则返回错误如下
三. 构造函数模式
new关键字能改变this的作用域
关键采用this关键字,对于this的理解,见ttps://www.cnblogs.com/yanhaijing/p/3685309.html(比较厉害的大牛)
function People(name,food){ //构造函数名首字母要大写,小写不会错,但习惯大写
this.name=name ;
this.food=food;
this.eat=function(){
alert(this.name+"喜欢吃"+this.food)//此处this指的是windows对象
}
}
var people1=new people("张三","苹果");
var people2=new people("李四","香蕉");
people1.eat()
people1==people2 //false 占用不同的内存空间
小总结:首先函数名首字母应该大写
与工厂模式不同的是,不需要在函数内部使用关键字new,两者相同的是都消耗很多内存
new关键字会改变this的作用域。this为当前调用的对象
创建完成构造函数后需要new一个实例化的对象赋值给一个变量,然后可以通过这个变量来调用构造函数里面的属性以及方法
构造函数模式可以传递参数
四 原型构造模式
构造函数都会有一个prototype(原型)属性,这个属性其实就是一个指针,它指向了一个对象,在这个对象里包含了可以共享给实例化对象的所有属性及方法
1.第一种写法
function People(){} //定义一个空函数
People.prototype.name="张三";
People.prototype.food="葡萄";
People.prototype.eat=function(){
alert(this.name+"喜欢吃"+this.food)
} //利用prototype属性来添加属性值和方法
var people1=new People();//创建实例化对象
var people2=new People();
people1.eat();
people1.eat==people2.eat //true; 判断是否是相同内存
alert(people1.constructor) //返回构造函数
2 第二种写法
function People(){}
People.prototype={
name:"小米",
food:" 火锅",
job :["IT","销售"],
eat:function(){
alert(this.name+"喜欢吃"+this.food)
}
}
var people1=new People();
people1.job.push("金融");
var people2=new People();
people2.job.push("服务");
alert(people1.job) //弹出为 IT ,销售,金融,服务
alert(people2.job) //弹出为 IT ,销售,金融,服务(由于两者地址相同,所以无论哪一方在向数组中添加,都会全部显示出来)
小总结:原型模式过于呆板,内容定义只能唯一,如果改变其中的属性值,则全部都会改变,没有使用this活泼,内存如果想修改其中一个实例化对象的属性或方法另一个实例对象也会随改变,这并非我们想要的结果,所以就会诞生了混合模式。
补充:
五 混合模式(构造函数模式+原型模式)
//构造函数模式可以传递参数,而且使用this关键字,活动性很强,但消耗内存过多
//原型模式消耗内存小,但活动性很差,因此两者合并,当需要传递参数时,则使用构造函数,当需要执行方法时,使用原型模式,
这是目前最为常用的创建对象的方式。
这种概念非常简单,即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果是,所有函数都只创建一次,而每个对象都具有自己的对象属性实例。
此外,组合模式还支持向构造函数传递参数,可谓是集两家之所长。
在所接触的JS库中,jQuery类型的封装就是使用组合模式来实例的!!!
function People(name,food){
this.name=name;
this.food=food;
}
People.prototype={
eat:function(){
alert(this.name+"喜欢吃"+this.food)
}
}
var people1=new People("小明","鸡蛋");
var people2=new People(“张三”,“水饺”)
people1.eat();
people2.eat();
people1.eat==people2.eat //true (eat属性属于原型模式,内存相同)
people1.name==people2.name //flase (name属于构造函数属性,内存不同)
六 动态模式
function People(name,food){
this.name=name;
this.food=food;
if(typeof this.eat!='function'){
alert("程序开始");
People.prototype.eat=function(){
alert(this.name+"喜欢吃"+this.food)
}
}
}
var people1=new People("小明","鸡蛋");
var people2=new People("小红","饺子");
people1.eat()
people2.eat();
//执行结果图:
有执行结果图看出动态模式更好的让我们避免创建对象多次初始化
详细代码见:(明天上传github)
有理解不正确的地方,希望大神们指点!
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1v9cvnavta0pn