類與實例
聲明一個類:
/** ES5聲明一個類**/
function Animail(){
this.name = 'name';
}
/** ES6聲明一個類**/
class Animal2{
constructor(){
this.name = "name";
}
}
/** 實例化**/
new Animal()
new Animal2()
類與繼承
第一種方式,藉助構造函數實現繼承
/** 藉助構造函數實現繼承**/
function parent1(){
this.name = "parent1"
}
function child1(){
parent1.call(this);//改變上下文,將父級構造函數指向到子級上
this.type='child1'
}
console.log(new Child())
第二種方式,藉助原型鏈實現繼承
/** 藉助原型鏈實現繼承**/
function parent1(){
this.name = "parent1"
}
function child1(){
this.type='child1'
}
child1.prototype = new parent1();//作用域由實例本身開始,向原型鏈上查找屬性
console.log(new child1())
缺點:
如果兩個實例同時用一個父類的原型,在修改原型鏈上的屬性時,會導致另一個實例的值也會被更改,因爲共用的一個父類實例在原型鏈上
第三種方式,組合方式實現繼承
/** 組合方式實現繼承**/
function parent1(){
this.name = "parent1"
}
function child1(){
parent1.call(this)//改變上下文,將父級構造函數指向到子級上
this.type='child1'
}
child1.prototype = new parent1();//作用域由實例本身開始,向原型鏈上查找屬性
console.log(new child1())
缺點:父級構造函數被執行了2次
第四種方式,優化1組合方式
/** 組合方式實現繼承**/
function parent1(){
this.name = "parent1"
}
function child1(){
parent1.call(this)//改變上下文,將父級構造函數指向到子級上
this.type='child1'
}
child1.prototype = parent1.prototype;//將父級原型對象賦值到子上
console.log(new child1())
缺點:child1的constructor指向的是parent,因爲parent和child共用一個原型對象
第五種方式,優化2組合方式
/** 組合方式實現繼承**/
function parent1(){
this.name = "parent1"
}
function child1(){
parent1.call(this)//改變上下文,將父級構造函數指向到子級上
this.type='child1'
}
child1.prototype = Object.create(parent1.prototype);//Object.create創建出來的原型對象就是參數(parent1的原型),而且達到了父類和子類原型對象的隔離
child1.prototype.constructor = child1;//將構造函數指向到實例的構造函數
console.log(new child1())
ES6繼承方式
class Animal{
//構造函數
constructor(props){
this.name=props.name||'未知';
}
eat(){
alert(this.name+"在吃東西...");
}
}
//class繼承
class Bird extends Animal{
//構造函數
constructor(props){
//調用實現父類的構造函數
super(props);
this.type=props.type||"未知";
}
fly(){
alert(this.name+"在飛...");
}
}