JavaScript函数的继承
什么是继承?通俗来说就是子承父业。
对象之间的继承(对象拷贝)
- for …in … 的作用以及语法
// for ... in .语句可以遍历对象属性
for(var key in 对象){
// key 每次遍历的属性名
}
获取属性值的方法:
【1】对象. 属性名
【2】对象[属性名]
可以通过遍历对象的成员,将这些属性添加给另一个对象。从而实现继承,这不是真正的继承,只是在拷贝对象的成员。
<script>
var fatherObj = {
name: 'father',
gender: 'male',
cars: ['劳斯莱斯','阿尔法','阿斯顿马丁'],
houses: ['独栋别墅', '古堡'],
play: function(){
console.log('高尔夫')
}
}
// 使用for.. in ..遍历对象中的属性
// 复制父级对象的成员给继承对象(子)
var sonObj = {
name: 'son'
}
for(var key in fatherObj){
// 不给sonObj复制同名的属性
if(sonObj[key]){
continue;
}
sonObj[key]=fatherObj[key]
}
console.dir(sonObj)
</script>
继承实现
- 原型链继承
因为原型链的存在,对象访问一个属性或方法时,会在自身找,找不到会到原型对象中找,所以我们可以借助原型对象来实现继承。
<script>
// 父类
function Person(){
this.name = 'zss',
this.gender = 'male',
this.age = '22'
}
// 子类
function Student(){
this.score = 100
}
// 改变子类原型对象
Student.prototype = new Person()
Student.prototype.constructor = Student
// 此时Studentd的实例s1,通过改变原型对象,继承了Person的属性
var s1 = new Student()
console.log(s1.constructor)
console.dir(s1)
</script>
- 此时,s1就继承了Person的属性。
- 借用构造函数实现继承
使用call()方法调用其他构造函数,并将其this变成当前对象。从而实现,当前对象继承其他构造函数的属性。
<script>
// 父类
function Father(name, gender, age) {
this.name = name,
this.gender = gender,
this.age = age,
console.log(this) // 指向window
}
Father()
// 子类
function Son(name, gender, age, score) {
// 此时,Son的this指向实例化的 s1对象
// 使用 call()方法,改变this指向
Father.call(this, name, gender, age) // 到这,就把 Father的 this 指向了 s1对象
this.score = score
}
var s1 = new Son('zwt', 'male', '18', 100)
console.dir(s1)
</script>
- 组合继承
组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。
<script>
// 父类型
function Teacher(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 将 Person 类中需共享的方法放到 prototype 中,实现复用
Teacher.prototype.sayHi = function () {
console.log('大家好,我是' + this.name);
}
//子类型
function Student(name, age, sex, score) {
//借用构造函数
Teacher.call(this, name, age, sex);
this.score = score;
}
// 改变Student的原型对象为Person的原型对象
// Student.prototype = Teacher.prototype; // 这样写有问题,Exam方法是 Student独有的,这样写导致 p1 也会有Exam方法
Student.prototype = new Teacher() // 此时 Student.prototype 中的 constructor 被重写了,会导致 s1.constructor === Teacher
Student.prototype.constructor = Student; //将 Student 原型对象的 constructor 指针重新指向 Student 本身
// 学生特有
Student.prototype.Exam = function () {
console.log('大家好,我是学生,我是要考试的');
}
//此时s1就继承J Person的属性和方法
var s1 = new Student('zs', 18, '男', 100);
console.dir(s1);
var p1 = new Teacher('zs2', 28, '男')
console.dir(p1)
// console.log(s1.constructor === Teacher)
</script>
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为了JavaScript中最常用的继承模式。而且,instanceof 和isPrototypeOf()也能够用于识别基于组合继承创建的对象。
- 👉 扩展传送门- - - JavaScript 原型链