前端面試題21----js的繼承方法
阿新 • • 發佈:2020-12-09
技術標籤:前端面試題javascriptes6
js繼承的幾種方法和es6繼承方法
繼承方法
原型鏈繼承
1.基本思想
利用原型鏈來實現繼承,超類的一個例項作為子類的原型
2、具體實現
function F() {}
//原型屬性,原型方法:
F.prototype.name="Lee";
F.prototype.age=33;
F.prototype.run=function(){
return this. name+" "+this.age+" running";
}
var f = new F();
console.log(f.name);
console.log(f.run);
3.優缺點
1)優點
- 簡單明瞭,容易實現
- 例項是子類的例項,實際上也是父類的一個例項
- 父類新增原型方法/原型屬性,子類都能訪問到
2)缺點
- 所有子類的例項的原型都共享同一個超類例項的屬性和方法
- 無法實現多繼承
- 在建立子類的例項時 不能向父類的建構函式傳遞引數
建構函式繼承
1。基本思想
通過使用call、apply方法可以在新建立的物件上執行建構函式,用父類的建構函式來增加子類的例項
2、具體實現
function F() {
// 屬性
this.name = name || 'dragon';
// 例項方法
this.sleep = function(){
console.log(this.name + '正在睡覺!');
}
}
function C(name){
F.call(this);
this.name = name || 'Tom';
}
var c=new C()
console. log(c.name);
console.log(c.sleep());
3.優缺點
1)優點
- 簡單明瞭,直接繼承超類建構函式的屬性和方法
2)缺點
- 無法繼承原型鏈上的屬性和方法
例項繼承
1.基本思想
為父類例項新增新特性,作為子類例項返回
2.具體實現
function F() {
// 屬性
this.name = name || 'Animal';
// 例項方法
this.sleep = function(){
console.log(this.name + '睡覺');
}
}
function C(name){
var instance = new F();
instance.name = name || 'Tom';
return instance;
}
var c = new C();
console.log(c.name);
console.log(c.sleep());
3.優缺點:
1)缺點:
- 不限制呼叫方式,不管是new 子類()還是子類(),返回的物件具有相同的效果
2)缺點:
- 例項是父類的例項,不是子類的例項
- 不支援多繼承
組合繼承
1.基本思想
利用構造繼承和原型鏈組合
2.具體實現
function F() {
// 屬性
this.name = name || 'Animal';
// 例項方法
this.sleep = function(){
console.log(this.name + '正在睡覺!');
}
}
function C(name){
F.call(this);//建構函式繼承
this.name = name || 'Tom';
}
C.prototype = new F();//原型繼承
var q=new C();
console.log(q.name);
console.log(q.sleep());
3.優缺點
1)優點
- 解決了構造繼承和原型鏈繼承的兩個問題
2)缺點
- 實際上子類上會擁有超類的兩份屬性,只是子類的屬性覆蓋了超類的屬性
原型式繼承
1.基本思想
採用原型式繼承並不需要定義一個類,傳入引數obj,生成一個繼承obj物件的物件
2、具體實現
var obj = {
name: "qw",
age: "12",
ada:"asd"
}
function F(o) {
function C() {}
C.prototype = o;
return new C();
}
var q= F(obj)
console.log(q.name);
console.log(q.age);
3.優缺點
1)優點:
- 直接通過物件生成一個繼承該物件的物件
2)缺點:
- 不是類式繼承,而是原型式基礎,缺少了類的概念
寄生式繼承(原型式+工廠模式 )
原型式+工廠模式
解決了組合繼承兩次呼叫建構函式的問題
1.基本思想
建立一個僅僅用於封裝繼承過程的函式,然後在內部以某種方式增強物件,最後返回物件
2、具體實現
//臨時中轉函式
function obj(o) {
function F() {}
F.prototype = o;
return new F();
}
//寄生函式
function create(o){
var q= obj(o);
//可以對f進行擴充套件
q.sleep = function(){
return this.name+”睡覺”;
}
return q;
}
var box = {
name: 'Lee',
age: 100,
family: ['Dad', 'Mom', 'Sister']
};
var box1 = create(box);
alert(box1.name);
alert(box1.run());
3.優缺點
1)優點:
- 原型式繼承的一種拓展
2)缺點:
- 依舊沒有類的概念
//臨時中轉函式
function obj(o) {
function F() {}
F.prototype = o;
return new F();
}
//寄生函式
function create(box,desk){
var q = obj(box.prototype);
q.construtor=d;
d.prototype=q;
}
function B(name,age){
this.name=name;
this.age=age;
}
B.prototype.run=function(){
return this.name + " " + this.age + " running..."
}
function D(name,age){
Box.call(this,name,age);
}
//通過寄生組合繼承來實現
create(B,D);//替代D.prototype=new B();
var d= new D('Lee',100);
alert(d.run());
3.優缺點
1)優點:
完美實現繼承,解決了組合式繼承帶兩份屬性的問題
2)缺點:
過於繁瑣,故不如組合繼承
ES6的繼承
通過extends關鍵字
class father{
constructor(name){
this.name=name
this.names=[1,2,3]
}
getname(){
console.log(this.name);
}
}
class child extends father{
constructor(name){
super(name);
}
sayHello(){
console.log("sayHello");
}
static hh(){
console.log("hh")
}
}
var cc=new child("juanjuan");
cc.sayHello();
cc.getname(); //juanjuan
child.hh(); //hh
cc.names.push("wqwq");
var c1=new child("sasasa");
console.log(c1.names) //[1,2,3]