JS 有哪些方式可以實現繼承?
繼承的含義:
繼承是面向對象編程中的一個重要概念,通過繼承可以使子類的實例擁有在父類中定義的屬性和方法。
1、原型鏈繼承
function UserBase(){
}
function User(){
}
User.prototype = new UserBase();
將父類的實例作爲子類的原型。
-
(1)不能向構造函數傳參,無法實現多繼承
-
(2)來自原型對象的引用屬性是所有實例共享的
2、構造繼承
實際上使用父類的構造函數來增強子類,等於是把父類的構造函數複製給子類。
function UserBase(){
}
function User(userName) {
UserBase.call(this);
this.userName = userName;
}
let user = new User("鬼鬼")
user.userName;
優點:
-
(1)可以向構造函數傳參數
-
(2)可以實現多繼承,多 call 幾個
缺點:
-
(1)無法實現函數複用
-
(2)只能繼承父類的屬性和方法,不能繼承父類的原型
3、實例繼承
爲父類實例添加新屬性,作爲子類實例返回。
function UserBase(){
}
function User(userName) {
let userBase = new UserBase();
userBase.userName = userName;
return userBase;
}
let user = new User("鬼鬼")
user.userName;
- 缺點:無法實現多繼承
4、拷貝繼承
function UserBase(userName){
}
UserBase.prototype.showInfo = function(){
console.log(this.userName)
}
function User(userName) {
let userBase = new UserBase();
for (let attr in userBase) {
User.prototype[attr] = userBase[attr];
}
this.userName = userName;
}
let user = new User("鬼鬼")
user.showInfo();
-
優點:支持多繼承
-
缺點:佔用內存高,因爲要用 for in 循環來拷貝父類屬性/方法
不可枚舉方法拷貝不了
5、組合繼承
通過調用父類構造函數,繼承了父類的屬性,並保留了傳參的優點。
然後再將父類實例作爲子類原型,實現了函數複用。
function UserBase(userName){
this.userName = userName
}
UserBase.prototype.showInfo = function(){
console.log(this.userName)
}
function User (userName){
//call方式
UserBase.call(this,userName)
//apply方式
UserBase.apply(this,[userName])
}
User.prototype = new UserBase()
let user = new User("鬼鬼")
user.showInfo();
優點:
-
(1)繼承父類的屬性和方法,也繼承了父類的原型
-
(2)可傳參,函數可複用
缺點:
調用了兩次父類構造函數
6、寄生組合繼承
通過寄生的方式,去掉了父類的實例屬性,在調用父類構造函數時,
就不會初始化兩次實例方法,避免了組合繼承的缺點
function UserBase(userName){
this.userName = userName
}
UserBase.prototype.showInfo = function(){
console.log(this.userName)
}
function User (userName){
UserBase.call(this,userName)
}
User.prototype = Object.create(UserBase.prototype)
User.prototype.constructor = User
let user = new User("鬼鬼")
user.showInfo();
7、Class 繼承
class UserBase{
constructor(userName){
this.userName = userName
}
showInfo(){
console.log(this.userName)
}
}
class User extends UserBase{
constructor(value){
super(value)
}
}
var user = new User("鬼鬼")
user.showInfo();
參考資料
-
https://blog.csdn.net/guoqing2016/article/details/106418081/
-
http://www.bubuko.com/infodetail-2556919.html
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/abJtYTIqjwmjbwHFNLgicg