(今天主要来讲三大特性之一的封装)
面向过程(POP):关注点在于做了什么,描述的是发展的过程。
面向对象(OOP):关注点在于能做什么,做的过程,描述的是对象与对象之间的关系。
一.什么是面向对象
1.面向对象不是语法,是一个思想,是一种编程模式
2.面向对象的特点:继承、多态、封装
3.面向对象的优势:
高内聚低耦合(将相关度比较高的部分尽可能的集中,不要分散就是高内聚,将两个相关的模块尽可以能把依赖的部分降低到最小,不要让两个系统产生强依赖就是低耦合)
高内聚
高内聚就好比咱们吃货所热爱的麻辣烫、大杂烩。相比醋溜白菜、油麦菜那些一个个细分出来的名菜,大杂烩、麻辣烫就实现了高内聚,将大多数的蔬菜都集中在了一起,让想吃菜的朋友一次将各种蔬菜吃个够。
低耦合
耦合性(Coupling)也叫耦合度,是对模块间关联程度的度量,指模块之间的依赖关系
好比你经常吃的扬州蛋炒饭,它就耦合度很高,由于将”蛋”“饭”炒在一起,所以假如你又想吃茄子拌饭了,那将蛋炒饭中的鸡蛋换成茄子很困难,所以只能另炒一盘,想吃鸡蛋面也是同样的道理,所以扬州蛋炒饭是“高耦合的”,以至于”可维护性”比较差。
可维护性高
面向过程就好比将所有的衣服放在一个柜子里面,如果我们要拿其中一件衣服,就很有可能将其他衣服打乱,从而引发很多问题
面向过程就是将一个大柜子分成了一个个的小柜子,将每一件衣服都放在一个小柜子里面,这样就算我们拿其中的一件衣服,也不会弄乱其他柜子中的衣服
二.如何创建对象
1、基于Object的方式创建对象
var yt = new Object(); // new 实例化对象
//属性 yt.name = '阎涛';
//属性 yt.age = 19;
//方法 yt.show = function() {
var str = '我叫' + this.name + '年龄' + this.age + '岁'
document.write(str)
}
yt.show()
2.在为函数传递大量可选参数时,可考虑使用对象字面量
var yt = {
name: '阎涛',
age: 19,
show: function() {
var str = '我叫' + this.name + '今年' + this.age + '岁'
document.write(str)
}
}
yt.show()
三.封装对象
通过封装函数,直接调用,无需关心函数的实现过程。
工厂模式
软件工程领域的一种设计模式
抽象了创建对象的过程
通过函数封装创建对象的细节,就是把创建对象的过程封装在了函数中
工厂模式的弊端
1.不变的内容(属性、方法)每次重复调用都会开辟一个新的内存空间,浪费资源
2.原型对象与实例对象之间的关系不关联
//使用instanceof判断原型对象与实例化对象的关系时,返回false
console.log(user1 instanceof Yt);
四.构造函数
如何解决上述工厂模式的问题,js提出了一个解决的方法——构造函数为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。构造函数一般以大写字母开头构造函数也是函数,只不过可以用来创建对象,内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。
与工厂模式对比:
- 没有显式创建对象,创建对象使用的new 构造函数的方法
- 直接将属性和方法赋给了this对象
- 没有return
创建构造函数
注意:
(1)函数名习惯性定义前字母大写
(2) 生成实例new不能省略
要加function
function Yt(name, age) {
this.name_ = name,
this.age_ = age,
this.show = function() {
var str = '姓名:' + this.name_ + '<br>年龄' + this.age_
document.write(str)
}
}
var user1 = new Yt('阎涛', 19)
user1.show()
构造函数this的指向
构造函数也只是帮我们解决了函数与实例化对象直接没有关联的问题,构造函数每次创建实例化对象时也会开辟一个空间来储存同一个函数,会浪费内存,而且开辟一个新的空间需要时间,如果每次创建实例化对象都需要开辟空间,也会浪费时间
五.原型对象prototype
为了解决空间浪费问题,我们使用新的知识——原型
- 每个构造函数都有一个prototype(原型)属性
- 是一个指针,指向一个对象
- 这个对象的所有属性和方法,都会被构造函数的实例继承(共享)。
- 这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。
构造函数通过原型分配的函数是所有对象所共享的。
JavaScript规定,每一个构造函数都有一个prototype属性,指向另-个对象。
注意这个prototype就是个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在原型对象上,这样所有对象的实例就可以共享这些方法.
创建原型对象封装
function yt(name, age) {
this.name_ = name,
this.age_ = age
}
//原型prototype就是将构造函数不变的方法和属性直接给到构造函数的父(祖)辈,也就是protptype,这样以后谁在调用这个方法可以直接向protoptype拿
yt.prototype.show = function() {
var str = '我叫' + this.name_ + '今年' + this.age_ + '岁'
document.write(str)
}
var user1 = new yt('阎涛', 19)
user1.show()
这样就解决了浪费内存空间的问题