目录
一、面向过程
面向过程的核心是解决问题的过程。编程时分析解决问题的步骤,然后用函数实现这些步骤,最后再依次调用。面向过程的偏向于我们做一件事情的流程,先干什么,再干什么,通过控制代码,从而实现函数的顺序执行。
举例:把大象装进冰箱
- 打开冰箱
- 装进大象
- 关上冰箱
面向对象以步骤解决问题。
二、面向对象
核心是对象。关注每个对象在解决问题中的行为。把要解决的问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个对象在整个解决问题的步骤中的属性和行为。
举例:把大象装进冰箱
1、 属性:大象
行为:进入冰箱
2、属性:冰箱
行为:开门,关门
面向对象以功能划分问题。
特点:
(1)封装性:对象是属性(静态特征)和行为(动态特征)的结合体(封装体)。
(2)继承性:父类(基类)的属性和行为可以派生到子类中。子类不需要重复定义。
(3)多态性:同一个消息传递给不同的对象,得到的结果不同。
比较:
面向过程就相当于蛋炒饭,蛋跟饭均匀混合,即耦合度高;当有人不吃鸡蛋时,整盘蛋炒饭就没法吃,即可维护性低。并且每口米都均匀混合着鸡蛋,吃起来更可口,这就是性能高,但又无法换口味,即重用性低。
面向对象就相当于盖浇饭,饭跟菜分离开来,耦合度低,不合口味时只需要更换配菜,即可维护性高。饭菜并不均匀混合,相比较而言每一口的口感有参差,即性能低,方便更换配菜,即重用性高。
三、类
具体相同属性和行为的对象的抽象。类是对象的模板,对象是类的实例(是类的具体体现)。比如说大众品牌的车是一个类,在这个类下有各种各样的具体型号的车。
1、ES5中定义类:通过构造函数实现
function Student(name,age){ //构造函数,建议首字母大写,Student可以看作类
this.name = name;
this.age = age;
}var s1 = new Student('刘备',32); //s1就是对象
var s2 = new Student('小乔',18);
2、ES6中定义类的方法
2.1定义类
类是“特殊的函数”,就像你能够定义的函数表达式和函数声明一样,类语法有两个组成部分:类表达式和类声明。
(1) 类声明
定义类的一种方法是使用类声明。要声明一个类,你可以使用带有class
关键字的类名。
class 类名{
constructor([参数]){ //构造方法:用来初始化对象的成员
方法体;
}
}
*函数声明和类声明之间的一个重要区别在于, 函数声明会提升,类声明不会。你首先需要声明你的类,然后再访问它,否则类似以下的代码将抛出ReferenceError
let p = new Student();
class Student{ //使用class关键字定义类
}
(2) 类表达式
类表达式是定义类的另一种方法。类表达式可以命名或不命名。命名类表达式的名称是该类体的局部名称。
// 未命名/匿名类
let Box = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Box.name);
// 输出: "Box"
// 命名类
let Student = class Student2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Student.name);//通过类的(而不是一个实例的) name 属性来检索 Student2
// 输出: "Student2
2.2 初始化:constructor()
constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class
创建的对象。一个类只能拥有一个名为 “constructor”的特殊方法。如果类包含多个constructor
的方法,则将抛出 一个SyntaxError 。
强调:在ES6中constructor构造方法不能显示调用。
2.3 练习
设计雇员Employee类,记录雇员的情况,包括姓名、年薪、受雇时间, 要求定义MyDate类作为受雇时间,其中包括工作的年、月、日,并用相应的方法(构造方法、显示信息的方法)对Employee类进行设置。
class MyDate{
constructor(year,month,date){
this.year = year;
this.month = month;
this.date = date;
}
show(){
console.log(this.year+"年"+this.month+"月"+this.date+"日")
}
}
class Employee{
constructor(name,salary,workDate){
this.name = name;
this.salary = salary;
this.workDate = workDate;
}
disp(){
console.log("姓名:"+this.name);
console.log("年薪:"+this.salary);
console.log("受雇时间:");
this.workDate.show()
}
}
var work1 = new MyDate(2021,6,15);
var e1 = new Employee("周瑜",400000,work1);
e1.disp();
3、类的继承
3.1 父类
又称为基类或超类,被继承的类。
3.2 子类
又称为派生类。由父类派生来的类。
3.3 继承的实现
extends
关键字在 类声明 或 类表达式 中用于创建一个类作为另一个类的一个子类。
class 子类名 extends 父类名{
constructor(){
}
其他的成员方法
}
3.4 super关键字
代表父类,用来访问和调用父类的成员。
A、调用父类的构造方法:在子类的构造方法中调用父类的构造方法
在继承中,创建子类对象时必须先调用父类的构造方法,然后再调用
子类的构造方法,并且父类构造方法的调用必须是子类构造方法中
第一条语句。
B、super([参数]):调用父类的构造方法。
C、调用父类的普通方法:super.方法名([参数])。
class Father{
constructor(name,sex){ //无参的构造方法
this.name = name;
this.sex = sex;
}
getName(){
return this.name;
}
money(){
console.log(100)
}
}
class Son extends Father{
constructor(name,sex){
super('刘备','男'); //必须是子类构造方法的第一条语句
this.name = name;
this.sex = sex;
}
disp(){
console.log(super.getName());
console.log("姓名:",this.name);
console.log("性别:",this.sex);
}
}
var s1 = new Son('阿斗','男');
s1.money(); //继承了父类的money方法
console.log("父亲:",s1.getName());
s1.disp(); //调用自己的方法
4、实例成员和静态成员
4.1 实例成员
对象成员,构造函数中this上添加的成员。
eg:this.name中的name就是实例成员。
4.2 静态成员
所有对象共享的成员,不属于某个具体的对象。又称为类成员。构造函数本身上添加的成员。
- 类名.成员名 -- ES6
- 构造方法名.成员名 -- ES5