1、原型式继承:借助构造函数的原型对象实现继承,即 子构造函数.prototype = 父构造函数.prototype.
function SuperClass(){
this.name = 'lyj'
this.sayName = function () {
console.log('name:'+this.name)
}
}
//设置构造函数的原型
SuperClass.prototype.age = 22
SuperClass.prototype.fridends = ['lily','kangkang'];
SuperClass.prototype.showAge = function () {
console.log('age:'+this.age)
}
function SubClass() {
}
//这句执行表示子构造函数的constructor指向了父构造函数的的constructor
SubClass.prototype = SuperClass.prototype
//所以子构造函数需要修正constructor
SubClass.prototype.constructor = SubClass
//以上实现了继承,实例调用,实例的是子造函数
var child = new SubClass();
// child.sayName(); //这句会报错,不能继承构造函数的实例对象的成员
child.showAge(); //22
console.log(child.fridends)
缺点:只能继承父构造函数原型对象上的成员,不能继承父构造函数的实例对象的成员,同事父的原型对象和子的原型对象上的成员有共享问题。
2、原型链继承:即 子构造.prototype = 父构造函数的实例
function SuperClass(){
this.name = 'lyj'
this.age = 22
this.sayName = function () {
console.log('name:'+this.name)
}
}
//设置构造函数的原型
SuperClass.prototype.fridends = ['lily','kangkang'];
SuperClass.prototype.showAge = function () {
console.log('age:'+this.age)
}
function SubClass() {
}
//实现继承
SubClass.prototype = new SuperClass();
//修改constructor
SubClass.prototype.constructor = SubClass
//实例
let child = new SubClass()
child.sayName();
child.showAge();
console.log(child.age)
//修改实例的属性时,父构造函数的原型对象也会变化
child.fridends.push('wy')
console.log(child.fridends)
//看父函数的实例
let father = new SuperClass()
console.log(father.fridends)
缺点:不能给父构造函数传递参数,父子构造函数之间的原型对象有共享问题。
3、借用构造函数:使用call或apply借用其他构造函数的成员。
function Person(name){
this.name = name
this.friends = ['lyj','tll','wy']
this.sayName = function () {
console.log(this.name)
}
}
function Student(name) {
//使用call借用Person构造函数
Person.call(this,name)
}
//实例化测试
var stu = new Student('小王八');
stu.sayName();
console.log(stu.friends)
缺优点:可以解决给父构造函数传递参数的问题,但是获取不到父构造函数原型上的成员,也不存在共享问题。
4、组合继承:即 借用构造函数 + 原型链继承
function Person(name,age){
this.name = name
this.age = age
this.friends = ['lyj','tll','wy']
this.sayName = function () {
console.log(this.name)
}
}
//父构造函数的原型对象
Person.prototype.showAge = function () {
console.log(this.age)
}
function Student(name) {
//使用call借用Person构造函数
Person.call(this,name)
}
//设置继承
Student.prototype = new Person()
//修改constructor
Student.prototype.constructor = Student
//实例调用
var stu = new Student('lyj')
stu.sayName();//lyj
console.log(stu.friends)
//如果要使用age,需要实例化父构造函数
var per = new Person('jyl',22)
per.sayName()//jyl
per.showAge() //22
//不会改变子函数的值
stu.sayName() //lyj
stu.showAge()//undefined
5、借用构造函数 + 深拷贝
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构造函数
Person.call(this,name,age)
}
//使用深拷贝实现继承
deepCopy(Student.prototype,Person.prototype);
//修改子构造的constructor
Student.prototype.constructor = Student
//深拷贝函数(递归实现)
//将obj2的成员拷贝到obj1中,只拷贝实例成员
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]
}
}
}
}
//实例化使用
var stu = new Student('llllyj',25)
stu.sayName()
stu.showAge()
网友评论