一. 继承【知道】
1.1 什么是继承
- 生活中的继承
子承父业 - 程序中的继承
子类型继承父类型的成员 (把多个子类型的共同成员提取到父类型中)- 学生
- 老师
- 人
1.2 对象的“继承”
概念:继承是类型和类型之间的关系,对象的“继承”本质是对象的拷贝,把一个对象的所有成员拷贝给另一个对象。
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// 第一个对象
var obj1 = {name:'张三', age:18};
// 第二个对象
var obj2 = {
name:'李四',
age:17,
sex:'男',
sayHi:function () {
console.log('大家好,我叫' + this.name)
}
}
// 把一个对象中的属性和方法,拷贝到另一个对象中
function extend (parent,child) {
for (var key in parent) {
if (child[key] === undefined) {
child[key] = parent[key];
}
}
}
// 拷贝之前的obj1
console.log(obj1); // {name: "张三", age: 18}
// 把obj2中的属性或方法拷贝到obj1中
extend(obj2,obj1);
// 拷贝之后的obj1
console.log(obj1); // {name: "张三", age: 18, sex: "男", sayHi: ƒ}
1.3 原型继承
继承:类型和类型之间的关系
案例:学生类型、老师类型 继承 Person类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 人构造函数
function Person () {
this.name = '名字';
this.age = 18;
}
Person.prototype.sayHi = function() {
alert('大家好,我叫' + this.name);
};
// 学生构造函数
function Student (stuId) {
this.stuId = stuId;
}
// 老师构造函数
function Teacher (money) {
this.money = money;
}
// 通过学生的原型让学生继承人
Student.prototype = new Person();
Student.prototype.constructor = Student;
// 通过老师的原型让老师继承人
Teacher.prototype = new Person();
Teacher.prototype.constructor = Teacher;
// 创建学生对象
var stu1 = new Student(10010);
console.log(stu1);
// 创建老师对象
var t1 = new Teacher(100);
console.log(t1);图解
注意:当设置了构造函数的prototype之后,别忘记设置constructor
问题:原型继承,无法设置构造函数的参数Student.prototype = new Person();只执行一次,无法给属性传值,可以方便的继承父类型的原型中的方法,但是属性的继承无意义
1.4 借用构造函数
call方法
使用call可以改变函数中的this,并且可以立即调用函数
和bind不同的是,bind会返回一个新函数,而call是直接调用 。语法:函数名或方法名.call(obj [,params]);
- obj:函数名或方法名对应的函数体中的this的指向。
- params, 函数名或方法名调用时需要传入的参数(一个或多个),可选。
代码:
1
2
3
4
5
6
7
8
9
10
11// 规则:this 的指向是在代码执行时决定的。
function fn (age) {
this.age = age;
console.log(this);
}
// 直接调用函数
fn(50); // 当直接调用时,函数中的this执向window。 window.fn(50),window可以省略;
// 创建要给对象
var obj = {};
// 通过call让obj去借用window的fn,并立即执行
fn.call(obj,100); // 函数中this指向obj
借用构造函数实现继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// 人构造函数
function Person (name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
alert('大家好,我叫' + this.name);
};
// 学生构造函数
function Student (name,age,stuId) {
// 借用Person
Person.call(this,name,age);
this.stuId = stuId;
}
// 老师构造函数
function Teacher (name,age,money) {
// 借用Person
Person.call(this,name,age);
this.money = money;
}
// 创建学生对象
var stu1 = new Student('张三',17,'10086');
console.log(stu1);
// 创建老师对象
var t1 = new Teacher('孔子',18,10000000);
console.log(t1);
借用构造函数继承的问题:无法继承方法
1.5 组合继承
什么是组合继承?
就是让原型继承 和 借用继承一起使用。代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32// 人构造函数
function Person (name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
alert('大家好,我叫' + this.name);
};
// 学生构造函数
function Student (name,age,stuId) {
// 借用Person
Person.call(this,name,age);
this.stuId = stuId;
}
// 继承人原型中的方法
Student.prototype = Person.prototype;
// 老师构造函数
function Teacher (name,age,money) {
// 借用Person
Person.call(this,name,age);
this.money = money;
}
// 继承人原型中的方法
Teacher.prototype = Person.prototype;
// 创建学生对象
var stu1 = new Student('张三',17,'10086');
console.log(stu1);
// 创建老师对象
var t1 = new Teacher('孔子',18,10000000);
console.log(t1);新的问题
问题:若给学生的原型上增加一个考试方法exam,老师类型也会出现exam方法。
代码:
1
2
3
4
5Student.prototype.exam = function () {
alert('学生考试');
};
console.log(stu1);
console.log(t1);图示结果:
解决问题代码:
原因:Student的引用 和 Teacher的引用 指向同一个对象。
解决方式:为两个类型单独拷贝
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42// 把一个对象中的属性和方法,拷贝到另一个对象中
function extend (parent,child) {
for (var key in parent) {
if (child[key] === undefined) {
child[key] = parent[key];
}
}
}
// 人构造函数
function Person (name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
alert('大家好,我叫' + this.name);
};
// 学生构造函数
function Student (name,age,stuId) {
// 借用Person
Person.call(this,name,age);
this.stuId = stuId;
}
// 拷贝人原型中的方法
extend(Person.prototype, Student.prototype);
// 老师构造函数
function Teacher (name,age,money) {
// 借用Person
Person.call(this,name,age);
this.money = money;
}
// 拷贝人原型中的方法
extend(Person.prototype, Teacher.prototype);
// 创建学生对象
var stu1 = new Student('张三',17,'10086');
// 创建老师对象
var t1 = new Teacher('孔子',18,10000000);
// 给学生原型单独加上一个方法
Student.prototype.exam = function () {
alert('学生考试');
};
console.log(stu1);
console.log(t1);图示结果: