js继承
一,原型继承
// 父
function Person(){
this.type = '人类';
this.info = {time:5000}
}
Person.prototype.say = function(){
console.log('说话。。');
}
// 子
function Man(){
}
// 原型继承:让子的原型指向父的一个实例对象
Man.prototype = new Person();
var m = new Man();
console.log(m.type); //人类
m.say(); //说话。。
// 缺点
var m2 = new Man();
m2.info.time = 1000;
console.log(m.info.time); //1000
原型继承的缺点:
- 父类的引用类型属性会被所有子类实例共享,任何一个子类实例修改了父类的引用类型属性,其他子类实例都会受到影响
- 创建子类实例的时候,不能向父类传参
二,ES6的继承方法-class
- Es6新数据类型class, 用来创建对象
- constructor 构造器, 当调用new Person(), 构造器里的方法就会运行
class Person2{
// 构造器(其实就是es5里的构造函数)
constructor(nation){
this.nation = nation;
}
// 原型上的方法直接写就行
say(){
console.log(`这是一个${this.nation}人`);
}
// Person2自身上的方法-加上static
static sing(){
console.log('人类会唱歌');
}
}
// 实现继承
class Man2 extends Person2{
constructor(nation){
super(nation); //调用父类的构造函数
}
}
var m1 = new Man2('中国')
console.log(m1.nation); //中国
m1.say() //这是一个中国人
三,其他继承模式
1.借用构造函数继承
function Father(name) {
this.name = name;
this.info = {time:10};
this.say = function () {
console.log("hello");
};
}
function Child(name) {
// 调用Father方法-重点
Father.call(this, name);
}
var c = new Child('hhh')
console.log(c.name); //hhh
c.say() //hello
// 测试
var c2 = new Child('www')
c2.info.time = 0;
console.log(c.info.time); //10
优点
- 避免了引用类型属性被所有实例共享
- 可以向父类传参 缺点
- 父类原型上的东西无法继承
- 每次new子类都要调用父类
2.组合继承(原型继承和借用构造函数继承的组合)
function Father2(name, age) {
this.name = name;
this.age = age;
}
Father2.prototype.say = function() {
console.log('hello');
}
function Child2(name,age) {
Father2.call(this,name,age);
}
Child2.prototype = new Father2();
var child = new Child2('Tom', 22);
console.log(child); //Father2 { name: 'Tom', age: 22 }
child.say() //hello
优点
- 避免了引用类型属性被所有实例共享
- 可以向父类传参
- 也可以继承父类原型上的东西了 缺点
- 每次new子类都要调用父类
3.寄生式继承
就是创建一个封装的函数来增强原有对象的属性,跟借用构造函数一样,每个实例都会创建一遍方法
function createObj(o) {
// Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。
var clone = Object.create(o);
clone.sayName = function () {
console.log('hello');
}
return clone;
}
var father = {
name: '人',
nation: '中国',
sing:function(){
console.log('唱歌。。。');
}
}
var son = createObj(father);
// son继承了father,拥有father的属性,同时还拥有sayName的方法
console.log(son.nation + son.name); //中国人
son.sayName() //hello
son.sing() //唱歌。。。
4.寄生组合式继承
es5最完美的继承方式: 原型+借用构造函数+寄生
// 原型+借用构造函数+寄生
function Person3(){
this.type = '人类';
}
Person3.prototype.say = function(){
console.log('说话。。。');
}
function Man3(){
// 借用构造函数
Person3.call(this);
}
// 原型继承 + 寄生
Man3.prototype = Object.create(Person3.prototype);//这样就可以减少组合继承中多进行一次构造函数的调用
// 寄生 Man.prototype.__proto__ === Person.prototype;
Man.prototype.constructor = Man;
var man = new Man3();
console.log(man.type); //人类
man.say() //说话。。。