如视频网站有两种会员:(VIP会员是普通会员,普通会员不是VIP会员)
-
普通会员
-
属性:用户名、密码
-
方法:观看免费视频
-
-
VIP会员
-
属性:普通会员的所有属性、会员到期时间
-
方法:普通会员的所有方法、观看付费视频
-
如果我们需要使用构造函数来创建会员,如何书写构造函数才能实现上面的需求?
// 普通会员的构造函数
function User(username, password){
this.username = username;
this.password = password;
}
User.prototype.playFreeVideo = function(){
console.log('观看免费视频')
}
// VIP会员的构造函数
function VIPUser(username, password, expires){
this.username = username;
this.password = password;
this.expires = expires;
}
VIPUser.prototype.playFreeVideo = function(){
console.log('观看免费视频')
}
VIPUser.prototype.playPayVideo = function(){
console.log('观看付费视频')
}
上面的代码出现了两处重复代码:
-
VIPUser的构造函数中包含重复代码
this.username = username; this.password = password;
这段代码和User构造函数并没有区别,可以想象得到,将来也不会有区别,即:普通用户该有的属性,VIP用户一定有
-
VIPUser的原型上包含了重复代码
VIPUser.prototype.playFreeVideo = function(){ console.log('观看免费视频') }
这个方法和User上的同名方法逻辑完全一致,可以想象得到,将来也不会有区别,即:普通用户该有的方法,VIP用户一定有
处理构造器内部的重复
可以将VIPUser构造器改写为
function VIPUser(username, password, expires){ User.call(this, username, password); this.expires = expires; }
处理原型上的重复
即 Object.setPrototypeOf(VIPUser.prototype, User.prototype)
继承是面向对象的概念,它描述了两个对象类型(类,构造函数)之间的关系
如果在逻辑上可以描述为:A不一定是B,但B一定是A,则:B继承A、A派生B、A是B的父类、B是A的子类
子类的实例应该自动拥有父类的所有成员
继承具有两个特性:
-
单根性:子类最多只有一个父类
-
传递性:间接父类的成员会传递到子类中
如何在JS中封装继承
function inherit(Child, Parent){ // 在原型链上完成继承 Object.setPrototypeOf(Child.prototype, Parent.prototype); }