1集乔、原型式繼承:借助構(gòu)造函數(shù)的原型對(duì)象實(shí)現(xiàn)繼承具练,即 子構(gòu)造函數(shù).prototype = 父構(gòu)造函數(shù).prototype.
function SuperClass(){
this.name = 'lyj'
this.sayName = function () {
console.log('name:'+this.name)
}
}
//設(shè)置構(gòu)造函數(shù)的原型
SuperClass.prototype.age = 22
SuperClass.prototype.fridends = ['lily','kangkang'];
SuperClass.prototype.showAge = function () {
console.log('age:'+this.age)
}
function SubClass() {
}
//這句執(zhí)行表示子構(gòu)造函數(shù)的constructor指向了父構(gòu)造函數(shù)的的constructor
SubClass.prototype = SuperClass.prototype
//所以子構(gòu)造函數(shù)需要修正constructor
SubClass.prototype.constructor = SubClass
//以上實(shí)現(xiàn)了繼承葵第,實(shí)例調(diào)用舟肉,實(shí)例的是子造函數(shù)
var child = new SubClass();
// child.sayName(); //這句會(huì)報(bào)錯(cuò),不能繼承構(gòu)造函數(shù)的實(shí)例對(duì)象的成員
child.showAge(); //22
console.log(child.fridends)
缺點(diǎn):只能繼承父構(gòu)造函數(shù)原型對(duì)象上的成員躯喇,不能繼承父構(gòu)造函數(shù)的實(shí)例對(duì)象的成員坊夫,同事父的原型對(duì)象和子的原型對(duì)象上的成員有共享問題搬葬。
2碌秸、原型鏈繼承:即 子構(gòu)造.prototype = 父構(gòu)造函數(shù)的實(shí)例
function SuperClass(){
this.name = 'lyj'
this.age = 22
this.sayName = function () {
console.log('name:'+this.name)
}
}
//設(shè)置構(gòu)造函數(shù)的原型
SuperClass.prototype.fridends = ['lily','kangkang'];
SuperClass.prototype.showAge = function () {
console.log('age:'+this.age)
}
function SubClass() {
}
//實(shí)現(xiàn)繼承
SubClass.prototype = new SuperClass();
//修改constructor
SubClass.prototype.constructor = SubClass
//實(shí)例
let child = new SubClass()
child.sayName();
child.showAge();
console.log(child.age)
//修改實(shí)例的屬性時(shí)绍移,父構(gòu)造函數(shù)的原型對(duì)象也會(huì)變化
child.fridends.push('wy')
console.log(child.fridends)
//看父函數(shù)的實(shí)例
let father = new SuperClass()
console.log(father.fridends)
缺點(diǎn):不能給父構(gòu)造函數(shù)傳遞參數(shù)悄窃,父子構(gòu)造函數(shù)之間的原型對(duì)象有共享問題。
3蹂窖、借用構(gòu)造函數(shù):使用call或apply借用其他構(gòu)造函數(shù)的成員广匙。
function Person(name){
this.name = name
this.friends = ['lyj','tll','wy']
this.sayName = function () {
console.log(this.name)
}
}
function Student(name) {
//使用call借用Person構(gòu)造函數(shù)
Person.call(this,name)
}
//實(shí)例化測(cè)試
var stu = new Student('小王八');
stu.sayName();
console.log(stu.friends)
缺優(yōu)點(diǎn):可以解決給父構(gòu)造函數(shù)傳遞參數(shù)的問題,但是獲取不到父構(gòu)造函數(shù)原型上的成員恼策,也不存在共享問題。
4潮剪、組合繼承:即 借用構(gòu)造函數(shù) + 原型鏈繼承
function Person(name,age){
this.name = name
this.age = age
this.friends = ['lyj','tll','wy']
this.sayName = function () {
console.log(this.name)
}
}
//父構(gòu)造函數(shù)的原型對(duì)象
Person.prototype.showAge = function () {
console.log(this.age)
}
function Student(name) {
//使用call借用Person構(gòu)造函數(shù)
Person.call(this,name)
}
//設(shè)置繼承
Student.prototype = new Person()
//修改constructor
Student.prototype.constructor = Student
//實(shí)例調(diào)用
var stu = new Student('lyj')
stu.sayName();//lyj
console.log(stu.friends)
//如果要使用age涣楷,需要實(shí)例化父構(gòu)造函數(shù)
var per = new Person('jyl',22)
per.sayName()//jyl
per.showAge() //22
//不會(huì)改變子函數(shù)的值
stu.sayName() //lyj
stu.showAge()//undefined
5、借用構(gòu)造函數(shù) + 深拷貝
function Person(name,age){
this.name = name
this.age = age
this.friends = ['lyj','tll','wy']
this.sayName = function () {
console.log(this.name)
}
this.showAge = function () {
console.log(this.age)
}
}
function Student(name,age) {
//使用call借用Person構(gòu)造函數(shù)
Person.call(this,name,age)
}
//使用深拷貝實(shí)現(xiàn)繼承
deepCopy(Student.prototype,Person.prototype);
//修改子構(gòu)造的constructor
Student.prototype.constructor = Student
//深拷貝函數(shù)(遞歸實(shí)現(xiàn))
//將obj2的成員拷貝到obj1中抗碰,只拷貝實(shí)例成員
function deepCopy(obj1,obj2) {
for(var key in obj2){
if(obj2.hasOwnProperty(key)){
//判斷是否是引用類型的成員變量
if(typeof obj2[key] == 'object'){
obj1[key] = Array.isArray(obj2[key])?[]:{}
deepCopy(obj1[key],obj2[key])
}else{
obj1[key] = obj2[key]
}
}
}
}
//實(shí)例化使用
var stu = new Student('llllyj',25)
stu.sayName()
stu.showAge()