原型鏈的繼承
1.第一種繼承方式(原型鏈繼承)
function Super(){
this.company = '韓創(chuàng)';
this.members = [1,2,3];
}
Super.prototype.getName = function(){
console.log('super'+this.company)
}
function Sub(name,age){
this.name = name;
this.age = age;
}
Sub.prototype = new Super();
//繼承后要將構(gòu)造函數(shù)也指向自己
Sub.prototype.constructor = Sub;
let sub = new Sub('Bryan',18);
console.log(sub.hasOwnProperty('company'));// false
console.log(sub.hasOwnProperty('name'));// true
console.log(Sub.prototype.isPrototypeOf(sub));// true
console.log(Super.prototype.isPrototypeOf(sub));// true
/**第一次打印解析
從打印結(jié)果來看
1.父類對象 Super 里的 company 屬性,雖然繼承到了 派生對象 sub 身上,但是不屬于它的自身屬性
2.父類對象的原型已經(jīng)等于 派生對象 sub 的原型
*/
let p1 = new Sub('p1',18);
let p2 = new Sub('p2',20);
p1.members.push(5);
console.log(p2.members);//[1,2,3,5]
/**
* 第二次打印解析
* 新建了兩個對象 p1 和 p2 ,并且改變 p1 的屬性 members
* 從打印結(jié)果來看
* 雖然改變的p1對象的members,但是p2的members也被改變了
* 所以對于 原型鏈繼承 當原型中存在引用類型值時漏健,實例可以修改其值诊赊。
* **/
2.第二種繼承方式(第二種繼承方式)
function Staff(){
this.company = 'abc'
this.members = [1,2,3]
}
Staff.prototype.getCompany = function(){
console.log(this.company)
}
function Employee(name,age){
Staff.call(this);
this.name = name;
this.age = age;
}
Employee.prototype.say = function(){
console.log(this.name + this.age)
}
let user1 = new Employee('lily',19)
let user2 = new Employee('lucy',20)
user1.members.push(4)
console.log(user2.members);//[1,2,3]
console.log(user1.hasOwnProperty('company'));//true
console.log(Staff.prototype.isPrototypeOf(user1));//false
console.log(Staff.prototype.isPrototypeOf(user2));//false
console.log(user1.getCompany());//user1.getCompany is not a function
/**
* 存在的問題
* 只能繼承父對象的實例屬性和方法楚堤,
* 不能繼承父對象原型屬性和方法
* 無法實現(xiàn)函數(shù)復(fù)用纽绍,每個子對象都有父對象實例的副本粘衬,性能欠優(yōu)
* **/
3.第三種繼承方式(組合繼承)
function Animal(){
this.home = 'abc'
this.num = [1,2,3]
}
Animal.prototype.say = function(){
console.log(this.home)
}
function Dog(name,age) {
Animal.call(this);
this.name = name;
this.age = age;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.prototype.move = function(){
console.log('dog move')
}
let dog1 = new Dog('xiaohei',1);
let dog2 = new Dog('xiaobai',2);
dog1.num.push(4)
console.log(dog1.num);//[1,2,3,4]
console.log(dog2.num)//[1,2,3]
dog2.move()//dog move
dog2.say()//'abc'
console.log(dog1.hasOwnProperty('home'));//true
console.log(dog1.hasOwnProperty('num'));//true
console.log(Animal.prototype.isPrototypeOf(dog1));//true
/****
優(yōu)點
可以復(fù)用原型上定義的方法
可以保證每個函數(shù)有自己的屬性橄仆,可以解決原型中引用類型值被修改的問題
缺點
staff 會被調(diào)用 2 次:第 1 次是employee.prototype = new staff();
第 2 次是調(diào)用 staff.call(this)。
***/