js常见继承实现

1,原型链继承

function Parent() {  
    this.name = 'Parent';  
}  
function Child() {  
    this.age = 10;  
}  
Child.prototype = new Parent(); // Child的原型指向Parent的一个实例  
var child = new Child();  
console.log(child.name); // 输出: Parent

优点 简单明了,容易实现,在父类新增原型属性和方法,子类都能访问到。

缺点 所有的实例都指向同一个引用地址,修改一个原型上的属性或方法,其他都会改变。不能超类型的构造函数传递参数

2,借用构造函数继承

function Parent(name) {  
    this.name = name;  
}  
function Child(name, age) {  
    Parent.call(this, name); // 借用Parent的构造函数  
    this.age = age;  
}  
var child = new Child('Child', 10);  
console.log(child.name); // 输出: Child

优点:保证每个实例都有自己的属性可向父对象的构造函数传递参数。

缺点:方法不能被复用每个对象实例都会创建一个新的方法)。

3,组合继承

function Parent(name) {  
    this.name = name;  
}  
function Child(name, age) {  
    Parent.call(this, name); // 继承属性  
    this.age = age;  
}  
Child.prototype = new Parent(); // 继承方法  
 
var child = new Child('Child', 10);  
console.log(child.name); // 输出: Child

结合了上述两种方法的优点,既可以在子类实例上共享方法,又可以保证每个实例都有自己的属性。

4,寄生组合式继承

    function Parent(name) {  
        this.name = name;  
        this.colors = ['red', 'blue', 'green'];  
    }   
    Parent.prototype.sayName = function() {  
        console.log(this.name);  
    };  
      
    function Child(name, age) {  
        Parent.call(this, name); // 继承父类的属性  
        this.age = age;  
    }  
      
    // 寄生组合式继承的核心  
    function inheritPrototype(child, parent) {  
        var prototype = Object.create(parent.prototype); // 创建一个中间对象,其原型为父类的原型  
        prototype.constructor = child; // 此时constructor为Parent,修正中间对象的constructor属性为Child
        child.prototype = prototype; // 将子类的原型设置为中间对象  
    }  
    inheritPrototype(Child, Parent);  
      
    //Object.create可替换为此object函数避免es5之前不支持的情况
    function object(o) {
         function F(){}
         F.prototype = o
         return new F()
    }




    var child1 = new Child('Tom', 5);  
    child1.colors.push('black');  
    console.log(child1.name); // 输出 "Tom"  
    console.log(child1.age); // 输出 5  
    console.log(child1.colors); // 输出 ["red", "blue", "green", "black"]  
    child1.sayName(); // 输出 "Tom"  
      
    var child2 = new Child('Jerry', 4);  
    console.log(child2.name); // 输出 "Jerry"  
    console.log(child2.age); // 输出 4  
    console.log(child2.colors); // 输出 ["red", "blue", "green"]  
    child2.sayName(); // 输出 "Jerry"

寄生组合式继承通过创建一个中间对象来继承父类的原型,从而避免了组合式继承中需要调用父类构造函数两次的问题。这种方式有效地减少了不必要的开销,提高了继承的效率。

5,class继承

// 定义父类 Parent  
class Parent {  
    constructor(name) {  
        this.name = name;  
    }  
  
    // 父类的方法  
    sayHello() {  
        console.log(`Hello, my name is ${this.name} and I am a Parent.`);  
    }  
}  
  
// 定义子类 Child,继承自 Parent  
class Child extends Parent {  
    constructor(name, age) {  
        // 调用父类的constructor  
        super(name);  
        // 定义子类特有的属性  
        this.age = age;  
    }  
  
    // 子类重写父类的方法  
    sayHello() {  
        // 调用父类的方法(如果需要的话)  
        // super.sayHello();  
        // 定义子类特有的行为  
        console.log(`Hello, my name is ${this.name} and I am a Child. I am ${this.age} years old.`);  
    }  
  
    // 子类特有的方法  
    describeAge() {  
        console.log(`I am ${this.age} years old.`);  
    }  
}  
  
// 使用示例  
const parentInstance = new Parent('John');  
parentInstance.sayHello(); // 输出: Hello, my name is John and I am a Parent.  
  
const childInstance = new Child('Jane', 10);  
childInstance.sayHello(); // 输出: Hello, my name is Jane and I am a Child. I am 10 years old.  
childInstance.describeAge(); // 输出: I am 10 years old.

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值