大多數前端開發者在面試的時候,是否是常常被問到 怎樣實現JS中的繼承?
, 其實實現繼承的方式有多種。 原型鏈繼承,構造函數繼承,組合繼承
等等。在此文中,咱們重點介紹 原型鏈的方式。前端
靜態屬性es6
class es6{
}
es6.staticAttr = '靜態屬性'
複製代碼
靜態方法面試
class es6{
static a(){
console.log('靜態方法');
}
}
複製代碼
公有屬性或方法編程
class es6{
}
es6.prototype.publicFunc = () => {
console.log('公有方法');
}
複製代碼
從文中咱們能夠得出以下結論:bash
1. 類Duck經過prototye屬性指向其原型(內存空間)
2. 實duck例經過__proto__屬性指向原型
3. 原型prototype經過construcror指向類Duck
複製代碼
所以實現繼承,能夠將類Duck的prototype指向被繼承類(Animal)的實例(animal, 經過 new Animal建立):函數
Duck.prototype = new Animal;ui
繼承所有屬性和方法this
//定義基類
function Animal(){
this.name = 'Animal'; //私有屬性
}
Animal.fn = 'fn'; //靜態屬性
Animal.prototyep.eat = function(){ //公有方法或屬性
console.log('吃');
}
//定義子類
function Duck(){
this.type = 'Duck'; //私有屬性
}
Duck.prototype = new Animal;
let duck = new Duck;
duck.eat(); // 打印: 吃
console.log(duck.name); // 打印: Animal
複製代碼
只繼承公有方法 有時候顯然不想讓子類繼承父類的私有屬性, 就像子類不可能跟父類使用同一個名字同樣。這時能夠這樣實現繼承:spa
方式一. Duck.prototype.__proto__ = Animal.prototype; //__proto__屬性在object這節中有介紹
複製代碼
function Animal(){
this.name = 'Animal'; //私有屬性
}
Animal.prototyep.eat = function(){ //公有方法或屬性
console.log('吃');
}
//定義子類
function Duck(){
this.type = 'Duck'; //私有屬性
}
Duck.prototype.swim = function(){
console.log('游泳');
}
Duck.prototype.__proto__ = Animal.prototype; //只繼承Animal的公有方法或者屬性
let duck = new Duck;
duck.eat(); //打印: 吃, 在Duck的原型上找不到eat方法,就經過__proto_向上找到 Animal.prototype上的eat方法
duck.swim(); //打印: 游泳
console.log(duck.name); // 打印: undefined, 先會在Duck類上找name私有屬性,並且Animal.prototype沒有包含Animal類的私有屬性
複製代碼
方式二. Duck.prototype.__proto__ = Object.create(Animal.prototype);
複製代碼
方式三. 對方式二的一種實現
function create(prototype){
function Fn(){} //沒有任何私有屬性
Fn.prototype = prototype;
return new Fn();
}
Duck.prototype.__proto__ = create(Animal.prototype);
複製代碼
extends 關鍵字prototype
class Animal{
constructor(name){//私有屬性
this.name = name;
}
static a(){ //靜態方法
}
eat(){ //公有方法
console.log('吃');
}
}
class Duck extends Animal{
constructor(type){
super();
this.type = type;
}
swim(){
console.log('游泳');
}
}
複製代碼
上述內容基本上說明了,js中原型鏈繼承的基本原理。對於面向OOP編程。又前進了一大步。