ES6 之前并没有给我们提供extends
继承
我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
1.call():将父类的this指向子类的this,这样就可以实现子类继承父类的属性。
fun.call(thisArg,arg1,arg2,......)
thisArg
:当前调用函数 this 的指向对象arg1,arg2
: 传递的其他参数
function Father(uname, age) {// Father构造函数是父类
this.uname = uname;
this.age = age;
}
function Son(uname, age, score) {// Son构造函数是子类
Father.call(this, uname, age); // 子类继承父类的属性
this.score = score; // 子类可以拥有自己的特有属性
}
var son = new Son('张三', 18, 100);
console.log(son); // 输出结果:Son {uname: "张三", age: 18, score: 100}
2.借用构造函数继承父类型属性
核心原理: 通过 call()
把父类型的 this 指向子类型的 this,这样就可以实现子类型继承父类型的属性
<body>
<script>
// 借用父构造函数继承属性
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father.call(this, uname, age);
this.score = score;
}
var son = new Son('刘德华', 18, 100);
console.log(son);
</script>
</body>
3、利用原型对象继承父类型方法
将父类的实例对象作为子类的原型对象来使用
核心原理:
- 将子类所共享的方法提取出来,让子类的
prototype 原型对象 = new 父类()
- 本质: 子类原型对象等于是实例化父类,因为父类实例化之后另外开辟空间,就不会影响原来父类原型对象
- 将子类的
constructor
重新指向子类的构造函数
function Father() {}
Father.prototype.money = function() {console.log(100000);};
function Son() {}
Son.prototype = new Father(); // 将父类的实例对象作为子类的原型对象
Son.prototype.constructor = Son; // 将原型对象的constructor属性指向子类
new Son().money(); // 调用父类money()方法,输出结果:100000
Son.prototype.exam = function() {}; // 为子类增加exam()方法
console.log(Father.prototype.exam); // 子类不影响父类,输出结果:undefined
原型链示意图:
class语法的本质:类和构造函数的使用非常相似,可以互相替代。
class Person{}
console.log(Person.prototype); // 类也有原型对象
Person.prototype.money = function() {// 类也可以增加方法
console.log(100000);
};
new Person().money(); // 输出结果:100000