JavaScript语言这独特的继承方式你都了解吗?(六种)

本文深入探讨了JavaScript中的继承机制,包括原型链继承、构造继承、组合继承、寄生组合继承等四种常见方式,分析了它们的特点与优缺点。其中,寄生组合继承被推荐为最理想的继承方式,因为它高效且只调用一次父类构造函数。此外,还提及了原型式继承和寄生式继承两种不太常用的技术。
摘要由CSDN通过智能技术生成

前言

众所周知在JavaScript也有类的概念,但是JavaScript中的类不同于其他语言(java、c++等)的类。在那些面向类的语言中,类继承的本质是复制;而在JavaScript中严格来说并没有真正的类,它的类继承的方式比较特别,是通过原型链接来继承的,也就是说在实现类继承之后,再对父类的原型对象上的方法进行修改,子类也同样会受到影响。

好了,了解到了JavaScript不同于其他面向类的语言的独特的继承方式了,现在来聊聊JavaScript如何实现继承。这也是面试常考的一个重点,大家务必全部阅读完。

继承方式

1.原型链继承

function Cat(){ }
function Animal(){}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true 

介绍: 在这里我们可以看到 new 了一个空对象,这个空对象指向 Animal 并且 Cat.prototype 指向了这个空对象,这种就是基于原型链的继承。

特点: 基于原型链,既是父类的实例,也是子类的实例

缺点: 无法实现多继承

2.构造继承

function Animal(){}
function Cat(name){Animal.call(this);this.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);//Tomconsole.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true 

介绍: 使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给 子类(没用到原型)

特点: 可以实现多继承

缺点: 只能继承父类实例的属性和方法,不能继承原型上的属性和方法。

3.组合继承

function Animal(){}
function Cat(name){Animal.call(this);this.name = name || 'Tom';}Cat.prototype = new Animal();Cat.prototype.constructor = Cat;// Test Codevar cat = new Cat();console.log(cat.name);//Tomconsole.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true 

介绍: 相当于构造继承和原型链继承的组合体。通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

特点: 可以继承实例属性/方法,也可以继承原型属性/方法

缺点: 调用了两次父类构造函数,生成了两份实例

4.寄生组合继承

function Animal(){}
function Cat(name){Animal.call(this);this.name = name || 'Tom';}(function(){// 创建一个没有实例方法的类var Super = function(){};Super.prototype = Animal.prototype;//将实例作为子类的原型Cat.prototype = new Super();})();// Test Codevar cat = new Cat();console.log(cat.name);//Tomconsole.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true 

介绍: 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的 构造的时候,就不会初始化两次实例方法/属性,解决了组合继承的缺陷

优点: 寄生组合式继承的高效率体现在它只调用了一次父类型构造函数,避免了创建不必要的或多余的属性,与此同时,原型链还能保持不变。

推荐: 推荐使用该方式来实现继承,这也是目前来说最理想的继承方式了

还有两种是在其他博主那学习过来的,现在适用性不强,主要推荐使用寄生组合继承,大家可以了解一下:

5.原型式继承

function Animal(o) {function F() {}F.prototype = o;return new F();
}

var person = {name : 'wuyuchang',friends : ['wyc', 'Nicholas', 'Tim']
}

var anotherPerson = Animal(person);
anotherPerson.name = 'Greg';
anotherPerson.friends.push('Bob');

var anotherPerson2 = Animal(person);
anotherPerson2.name = 'Jack';
anotherPerson2.friends.push('Rose');

console.log(person.friends);// [ 'wyc', 'Nicholas', 'Tim', 'Bob', 'Rose' ] 

介绍: 原型式继承的的实现方法与普通继承的实现方法不同,原型式继承并没有使用严格意义上的构造函数,而是借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

6.寄生式继承

/* 原型式继承 */
function Animal(o) {function F() {}F.prototype = o;return new F();
}

/* 寄生式继承 */
function createAnother(original) {var clone = Animal(original);clone.sayHi = function() {console.log('hi');}return clone;
}

var person = {name : 'wuyuchang',friends : ['wyc', 'Nicholas', 'Rose']
}
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//hi 

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值