javaScript面向对象的程序设计(八)——继承
程序员文章站
2022-06-15 13:48:42
...
基类
//基类 父类
var Person = function(){
this.name = 'Marvin';
this.age = 20;
}
Person.prototype = {
say : function(){
console.log('Person.prototype - say');
}
}
构造函数
//派生类
/*构造函数方式*/
var Student = function(){
Person.call(this, arguments);
//子类也可以拥有自己的一些属性和方法
this.sID='000001'
}
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
原型方式
/*原型*/
var Student = function(){}
//将Student对象的原型指向新建的一个Person
Student.prototype = new Person();
Student.prototype.getTeacher = function(){
console.log('王书奎');
}
- 来自原型对象的引用属性是所有实例共享的
- 创建子类实例时,无法向父类构造函数传参
组合继承
var Student = function(){
Person.call(this, arguments);
this.age = 0;
}
//将Student对象的原型指向新建的一个Person
Student.prototype = new Person();
- 调用了两次父类构造函数,生成了两份实例
- 也行
寄生组合继承
var Student = function(){
Person.call(this, arguments);
this.age = 0;
}
(function(){
// 创建一个没有实例方法的类
var Ad = function(){};
Ad.prototype = Person.prototype;
//将实例作为子类的原型
Student.prototype = new Ad();
})();
- 最好的继承方式【麻烦些】
拷贝模式
ES6
ES6中实现了class的extends的继承的方式,
//基类
class Person {
constructor(name, age){
this.name = name;
this.age = age;
}
public say(){
console.log(this.name)
}
}
//派生类
class Student extends Person {
constructor(id) {
supper(name, age);
}
public listen(){
console.log(this.id);
}
}
基本代码
/****************************基类**************************/
/*基类*/
var Person = function(name,age){
this.name = name;
this.age = age;
this.base = function(){
return 'base function';
};
this.bsaePerson = function(){
return 'this bsaePerson function';
};
};
Person.prototype = {
say: function(){
return 'this is say function';
},
eat: function(){
return 'this is eat function'
}
}
/**********************构造函数继承************************/
/*
构造函数继承只能访问基类的自己的方法
实例不能访问构造函数原型的方法
*/
var Man = function(brithday,name,age){
this.brithday = brithday;
Person.call(this,name,age);
};
Man.prototype = {
brithday: function(){
return 'this is brithday function'
}
};
var Liu = new Man(1997,'sss', 40);
console.log(Liu);
console.log(Liu.brithday);
console.log(Liu.name);
console.log(Liu.age);
console.log(Liu.base());
console.log(Liu.bsaePerson());
//报错,不能访问基类原型中的方法
console.log(Liu.say())
/**************************** *原型继承*************************/
/*
原型继承的派生类能访问所有基类的搜有的属性和方法
无法向基类传递参数
将派生类的原型指向新建的构造函数
*/
var Man = function(brithday){
this.brithday = brithday;
}
Man.prototype = new Person('we',75);
var Liu = new Man('1997');
console.log(Liu);
console.log(Liu.name);
console.log(Liu.age);
console.log(Liu.brithday);
//构造函数的方法
console.log(Liu.base());
console.log(Liu.bsaePerson());
//构造函数的原型的方法和属性
console.log(Liu.say());
//
console.log(Liu instanceof Person);
console.log(Liu instanceof Man);
/************************* *实例继承***********************/
/*
能访问构造函数和自己和原型中的方法
将自己创建实例的方法封装为函数,并且返回这个对象
*/
var Man = function(name, age){
var o = new Person(name, age);
return o;
}
var Liu = new Man('Marvin', 50);
Liu.brithday = 70;
console.log(Liu);
console.log(Liu.name);
console.log(Liu.age);
console.log(Liu.brithday);
//构造函数的方法
console.log(Liu.base());
console.log(Liu.bsaePerson());
//构造函数的原型的方法和属性
console.log(Liu.say());
//true
console.log(Liu instanceof Person);
//false
console.log(Liu instanceof Man);
/ ****************************对象创建*************************/
/*
新增的实例函数
*/
//
var student= new Person('Marvin', 20);
student.listen = function(){
return 'this is listen function'
}
console.log('对象创建时原型,构造函数的所有属性和方法都相同');
console.log(student.name);
console.log(student.age);
console.log(student.say());
console.log(student.eat());
console.log(student.base());
console.log(student.bsaePerson());
console.log('对象创建时实例添加的自定义方法');
console.log(student.listen());
var teacher = new Person('Lili', 40);
teacher.listen = function(){
return 'this is teacher listen function'
}
console.log(teacher.name);
console.log(teacher.age);
console.log(teacher.listen());
/********************* *组合继承*******************************/
/*
调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
*/
var Man = function(brithday,name,age){
this.brithday = brithday;
Person.call(this,name,age);
}
Man.prototype = new Person();
var Liu = new Man(25,'Lili', 58);
console.log(Liu);
//基类中的属性
console.log(Liu.name);
console.log(Liu.age);
console.log(Liu.brithday);
//构造函数的自己的方法
console.log(Liu.bsaePerson());
console.log(Liu.base());
//构造函数原型中的方法
console.log(Liu.say());
console.log(Liu.eat());
/***************************************** *拷贝继承***************************************************/
/*
将属性全部拷贝一次
*/
var a = {
'name': 'Marvin',
'age': 50
};
var b = {
'brithday': 52
};
function extend(a, b){
var o = {};
for(var item in a) {
o[item] = b[item];
}
return o;
}
console.log(extend(a, b));
console.log(b);
console.log(a);
/***************************************** 寄生组合继承***************************************************/
/*
完美的继承
麻烦些
*/
var Man = function(name, age, brithday){
Person.call(this, name, age);
this.brithday = brithday;
};
(function(){
var O = function(){};
O.prototype = Person.prototype;
Man.prototype = new O();
Man.prototype.constructor = Man;
})();
var Liu = new Man('Marvin', 50, '1997');
console.log(Liu);
//基类中的属性
console.log(Liu.name);
console.log(Liu.age);
console.log(Liu.brithday);
//构造函数的自己的方法
console.log(Liu.bsaePerson());
console.log(Liu.base());
//构造函数原型中的方法
console.log(Liu.say());
console.log(Liu.eat());