在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式。对于为什么要模拟类语言的面向对象,我个人认为:某些情况下,原型模式能够提供一定的便利,但在复杂的应用中,基于原型的面向对象系统在抽象性与继承性方面差强人意。由于JavaScript是唯一一个被各大浏览器支持的脚本语言,所以各路高手不得不使用各种方法来提高语言的便利性,优化的结果就是其编写的代码越来越像类语言中的面向对象方式,从而也掩盖了JavaScript原型系统的本质。
什么是面向对象呢?
面向对象【Oriented Object】:不是一个技术,而是一种处理问题的思路,是一种编程思想,是对传统面向过程编程的一种补充和完善。
面向对象的特性:
(1)是对零散数据的封装;
> 特性1:对零散数据的封装
第一种封装,通过常规的JSON对象封装,存在缺陷
第二种封装:解决第一种封装中由于代码的重复量造成的复杂度的提升
上面两种封装模式,都是通过JSON数据对象的形式进行封装,只是满足面向对象编程中的封装的特征。不是完整的面向对象!
但是这样的封装存在着以下问题
>>> 对象和类之间没有任何关系
>>> 同一个类的多个对象之间没有任何关系
> 这样原始的对象封装,在项目开发时,要使用在什么地方:
> 当程序中,某个对象只能出现一次的时候。使用JSON对象直接封装
> 当程序中的某个类型可能出现多个对象的时候,不要使用这样的形式封装。
(2)提高代码的复用性【重复使用的特性】;
(3)降低代码之间的耦合【耦合:依赖】提高代码的健壮性
(4)提高项目的扩展性【软件开发的OCP原则:开闭原则】
面向对象的核心:类和对象
类:类型的简称,类型~数据类型的简称,就是一个代号,一种数据类型的描述如人~。类是对象抽象出来的一个概念。
对象:就是类型的某一个具体的实体,一个具体已经存在实际的物体!对象是类型指代的具体存在的某一个问题。
>>>json分装就面向对象的思想来说,存在一定的缺陷,在这种的封装的模式下,如果对象比较多就会让代码的复杂度提升的非常严重。
面向对象的过程:
(1)面向对象分析 OOA
(2)面向对象设计 OOD
(3)面向对象编程 OOP
(4)面向对象测试 OOT
面向对象的特征:
>封装:将零散的数据封装起来,进行统一的管理和支配;
>继承:通过不同对象之间的关联关系,来完成提升代码复用性和扩展性的目的;
>多态:运行的过程中,对象在不同的环境下会表现出不同的状态。
面向对象的使用范围:
>不要在小效果上使用面向对象;
>不要在独立的效果上使用面向对象;
>通常情况下,在项目中进行公共效果的开发和批量数据的处理时,使用面向对象的简化开发。
通过JSON数据来模拟一种数据类型:
var People = {
name:””,
age:0,
eat:function(){
console.log(name + “吃饭了”);
}
}
上面就是一个模拟的人的类型,正常情况下要根据这个类型的模板,来创建具体的实例对象!
var houZi = {}
houZi.name = “侯局长”;
houZi.age = 43;
houZi.eat = function() {
console.log(this.name + “吃饭了…”);
}
数据已经封装完成,将name、age、eat()作为一个人的属性和行为被封装在一起,也就是将零散的数据封装整合到一起方便程序中进行统一的管理和使用。上面的封装方式使用的时候一定要注意适用范围
1. 比较适用于程序中某个类型只存在唯一实例对象的形式。
2.不适合某个类型有多个对象的形式,多个实例书写方式就会很麻烦,实例和类之间没有关联关系、实例和实例之间没有关联关系
函数封装模式
function People(name, age) {
return {
name:name,
age:age
}
}
创建对象就会变得非常简单var leaderGao = People(“高经理”, 30);
var chaiQianChang = People(“拆迁常”, 35);
一定程度上降低了代码的复杂度,提高了代码的可用性。不过只是对上一种方式的封装,依然体现不出leaderGao、chaiQianChang实例和People类型之间的关系。构造函数
定义类型的语法结构:
function People (name, age){
this.name = name;
this.age = age;
this.eat = function() {
console.log(this.name + “吃饭了…”);
}
}
var jianChaJi = new People(“季检察长”, 50);
var chenHai = new People(“陈海”, 38);
我们重新审视创建的对象jianChaJi和chenHai
通过new关键字创建的对象,就会有自己的一个constructor属性,指向对象的构造函数,也就是我们定义的类型;通过这样的方式来反映类型和对象之间的关系
console.log(jianChaJi.constructor);
console.log(chenHai.constructor);
同样的,JS提供了另一个对象操作符号instanceof验证类型和对象之间的关系- console.log(jianChaJi instanceof People);
- console.log(chenHai instanceof People);
继承:
什么是继承:
在继承中,会出现两个类型【父类、子类,子类继承父类的属性和行为】
继承是用来做什么的:
继承是通过子类继承父类实现父类中代码的重复利用!
继承的使用注意事项:
尽量让一个父类有一个或者多个子类
一个子类只继承一个父类
继承的第一种方式:通过apply/call实现假继承
apply/call方法都是通过改变函数中第一个参数的指向来达到扩展代码功能的目的
唯一的区别就是apply和call后面的参数不一样!
var Animal = function(name, color) {
this.name = name;
this.color = color;
}
Animal.prototype.eat = function() {console.log("吃肉");}
var Cat = function(name, color, age, type) {
// Animal.apply(this, [name, color]);
Animal.call(this, name, color);
this.age = age;
this.type = type;
}
Cat.prototype.caches = function() {console.log("抓老鼠..");}
var cat = new Cat("tom", "黑色", 48, "猫科");
console.log(cat);*/
2.通过prototype和空对象进行间接继承
我对原生面向对象的理解就这样