前端之JS-关于类的继承与多态

原型链继承(实例.prototype = new 原型)

该方法有一个弊端:1)实例属性无法传给原型;2)多个实例共用原型的构造方法,导致引用数据类型共用

function Person() {
    this.name = 'sss';
    this.age = 12;
    this.friends = ['aaa', 'bbb', 'ccc'];
    this.say = function() {
        console.log(this.name + this.age);
    };
    this.social = function() {
        console.log('-----friends', this.friends);
    }
 }
function Child() {
    this.name = 'fff';
 }
 Child.prototype = new Person(); // 将Child继承父类Person
 var person = new Person();
 var child = new Child();
 person.say(); // sss12
 child.say(); // fff12 // 继承父类age属性
 child.name = 'change'; 
 child.age = 15;
 child.friends.push('ddd');
 var child2 = new Child(); // 另一个实例
 child.say(); // change15; 子类的属性覆盖父类
 child2.say(); 
 child.social(); //['aaa','bbb','ccc','ddd']
 child2.social(); // 多个实例共享原型的一个构造方法,导致引用类型变量共用,输出['aaa','bbb','ccc','ddd']
 person.say();

当继承的函数被调用时,this指向的是继承的函数,而非继承的原型的函数。当在继承的对象中查找某个属性的时候,js不仅会在当前属性查找,还会沿着原型链一直查找,当要查找的是不存在的属性时,甚至会遍历原型链上所有对象,影响性能。

借用构造函数

function Colors() {
    this.color = ['red', 'green', 'yellow'];
}
function Child() {
    Colors.call(this); // 这里把原型构造函数的this指向实例,实现继承
}
var child = new Child();
child.color.push('black');
console.log(child.color); // ['red','green','yellow', 'black']
var child2 = new Child();
console.log(child2.color); // 每个实例有自己的构造方法,['red','green','yellow']

组合继承:利用原型链实现实例对父类的继承,通过借用构造函数实现父类对实例属性的继承

代码就是以上两种的组合;

如何用ES6实现类和继承

注意:ES6的class可以实现类的封装,但是本质还是原型链,只是语法糖。

class Parents {
    // 构造属性
    constructor(name) {
        this.name = name;
    }
    // 方法
    static sayHello() {
        console.log('hello');
    }
    sayName() {
        console.log(this.name);
        return this.name;
    }
}
// 子类继承父类
class Child extends Parents {
    constructor(name, age) {
        super(name); // 覆盖父类的属性
        this.age = age;
    }
    sayAge() {
        console.log(this.age);
    }
}
var parent = new Parents('Wang');
var child = new Child('Li', 15);
console.log('parent: ', parent); // parent:  Parent {name: "Parent"}
Parents.sayHello(); // 用static修饰的静态方法不能被实例调用,只能原型的方式调用
parent.sayName(); // Wang
console.log('child: ', child); // child:  Child {name: "Child", age: 15}
Child.sayHello(); // hello
child.sayName(); // my name is Child
child.sayAge(); // my age is 18
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值