面向对象编程
介绍
面向对象分析OOA
分析问题,需求:
- 将任务不断的拆分,拆分成更具体的小任务,使用分工协作的形式,解决所有的小任务
- 更具体的小任务:能直接解决的小任务
面向对象设计OOD
高内聚(忠诚度),低耦合(依赖)
面向对象编程OOP
优点
继承
封装
多态
设计模式
工厂模式
工厂模式抽象了具体对象的过程。也就是说,发明了一种函数,把对象放到函数里,用函数封装创建对象的细节。
function createPerson (name,age) {
var o = {
name : name,
age : age,
sayName : function () {
alert(this.name)
}
}
return o;
}
var person1 = createPerson("Tom",14);
var person2 = createPerson("Jerry",18)
console.log(person1 instanceof Object) //true
console.log(person1 instanceof createPerson) //false
instanceof 用于检测数据类型
var aa = []
console.log(aa instanceof Array) //true
工厂模式解决了代码复用的问题,但是却没有解决对象识别的问题。即创建的所有实例都是Object类型。
为了解决这一问题,就有了构造函数模式
构造函数模式
可以被构造的函数和正常函数的区别:首字母大写(大驼峰)
function Person (name,age) {
this.name = name;
this.age = age;
this.sayName = function () {
alert(this.name)
}
}
var person1 = new Person('Tom',14);
var Person2 = new Person('Jerry',18);
- 构造函数 Person 有一个prototype(原型)属性,这个属性是一个指针,指向一个对象即:Person.prototype(原型对象);
- 实例person1 person2也有一个[[prototype]]属性或者叫_proto_,这个属性 也指向Person.prototype;
- 构造函数和实例都共享Person.prototype里的属性和方法;
- Person.prototype里有一个 constructor属性,这个属性也是一个指针,指向构造函数Person。这样以来,实例也指向了Person,那么实例也共享了构造函数的属性和方法。
- 构造函数、实例、原型对象里所有的属性和方法都是共享的。
构造函数解决了对象识别问题,我们在这个例子中创建的对所有对象既是Object的实例,同时,也是Person的实例。这一点通过instanceof操作符可以得到验证。
new的原理
- 自动创建一个新对象
- 将这个构造函数的作用域赋给新对象(因此this就指向了这个新对象)
- 执行构造函数中的代码(为这个新对象添加属性)
- 检测函数是否主动返回对象,没有,就返回第一步创建的新对象
构造函数与普通函数的区别
构造函数和普通函数的唯一区别,在于调用它们的方式不同。
当作构造函数使用
function Person (name,age) {
console.log(this);
this.name = name;
this.age = age;
}
var person = new Person("andy",21);
需要注意的是,this指向构造函数Person
当作普通函数使用
function Person (name,age) {
console.log(this)
}
Person()
this指向widow.
构造函数的问题
构造函数虽然好用,但也有缺点。既每个new出来的实例里的方法都要重新创建一遍。在前面的例子中person1 person2 都有一个sayName方法,但这两个方法不是同一个Function实例!每个实例的方法 都是不同的,不相等的。这是不合理的!
function Person (name) {
this.name = name;
this.sayName = new Function ("alert(this.name)")
}
function Person (name) {
this.name = name;
this.sayName = function () {
alert(this.name)
}
}
alert( person1.sayName == person2.sayName ) //false
由此可见,完成同样任务的函数确实没必要每个实例,就实例一次。
于是,有需求,就有解决方案:原型模式。
原型模式
TBD
组合构造函数原型模式
构造函数与原型混合的模式是目前使用最广泛、认同度最高的一种创建定义类型的方法。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。
每个实例都会有自己的一份实例属性的副本,同时共享着对方法的引用,最大限度节省内存。同时,这种混杂模式还支持向构造函数传递参数,可谓是集两种模式之长。
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["Machiel","Dophe"];
};
Person.prototype={
constructor:"Person",
sayName:function(){
alert(this.name)
}
};
var person=new Person("Niche",12,"Software")
console.log(person.friends);
person.sayName();
//构造函数实现实例属性的副本,原型实现方法的共享
function Peason(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Peason.prototype.show = function () {
console.log(this.name, this.age, this.sex);
}
let andy = new Peason("andy",25,1);
let yuehui = new Peason("yuehui",23,1);
andy.show();//"andy",25,1
andy.name = "xiaoandy";
andy.show();//"xiaoandy",25,1
yuehui.show = function () {
console.log(this.name,this.age)
}
yuehui.show();//"yuehui",23 只会在yuehui对象中新增一个方法,不会修改到原型里的方法,如果使用yuehui.prototype.show去修改,就会修改共享方法
andy.show()//"xiaoandy",25,1
动态原型模式
TBD
寄生构造函数模式
TBD
稳妥构造函数模式
TBD
总结
什么是工厂模式 ?
工厂模式就是抽象了具体对象细节过程的方法。这个方法以函数的形式封装实现的细节。实现了重复调用的功能。
什么是构造函数模式 ?
构造函数模式就是创建一个对象,new 这个对象就是对象的实例。实现重复调用的同时,它的实例 也有了QQVIP的尊贵特权 ,即实例可以标识为特定的类型。有了这个标识 可以更好的识别出,谁是数组类型,谁是函数类型,然后你 typeof arr 或 typeof fun
一看,真的是Array类型,functiong类型。你也可以自定义自己想要的类型,这样大大的增加了JS的拓展性。
什么是原型模式 ?
首先我们要知道,我们创建的每一个函数都有一个隐藏属性,也就是原型属性。这个原型属性指向一个原型对象。且所有实例和构造函数 都指向这个原型对象,共享原型对象的所有方法和属性。
我们通过操作原型对象达到 实例共享属性方法的目的,就是原型模式。
同时,因为实例都是引用原型对象的属性和方法,也避免了构造函数模式下所有实例都有各自的方法的弊端。