javascript如何实现继承?
【什么是继承?】
-
子类拥有父类的特征和行为
- 特征==属性
- 行为==方法
【怎么做?】
//父类
function Person(name){//给构造函数添加了参数
this.name = name;
this.msg = function(){
alert(this.name);
}
}
Person.prototype.age = 10;//给构造函数添加了原型属性
方法一:原型链继承
==步骤1:创建一个子类,并把子类的原型对象指向父类的实例**(关键点)**==
//创建子类
function Sub(){
this.name = 'roy';
}
//子类的原型对象指向父类实例
Sub.prototype = new Person();
步骤2:创建子类实例,此时子类实例已经完成继承
var sub1 = new Sub();
步骤3:验证是否继承成功(其实真正实现继承仅上面两步即可,这一步属于调用父类,检验是否继承成功)
console.log(sub1.age);//10
//instanceof 判断元素是否在另一个元素的原型链上
//sub1继承了Person的属性,返回true
console.log(sub1 instanceof Person);//true
【分析】
- 优点
- 实现了继承
- √ 实例的构造函数的属性(即子类的构造函数属性)
- √ 父类的构造函数的属性
- √ 父类原型的属性
- 实现了继承
- 缺点
- 新实例无法向父类构造函数传参
- 【原因】步骤二时,是通过子类来创建新实例,而不是通过父类创建实例
- 继承单一
- 【原因】如图(1)一个子类仅继承一个父类
- 修改子类实例的属性会改到父类的属性。
- 【原因】如图(1)
- 新实例无法向父类构造函数传参
方法二:构造函数继承
==步骤1:在子类构造函数内回调父类构造函数(关键点)==
function Sub(){
Person.call(this,'roy');
this.age = 12;
}
步骤2:创建子类实例
var sub1 = new Sub();
步骤3:检验是否继承成功
console.log(sub1.name);//roy
console.log(sub1.age);//12
console.log(sub1 instanceof Person);//false
【分析】
- 优点
- 实现了继承:
- √ 继承父类构造函数的属性
- ✕ 继承父类原型上的属性(如图(3))
- 可以向父类构造函数传参
- 实现了继承:
- 缺点
- 无法实现父类构造函数的复用
- 【原因】用一次,重新调用父类构造函数一次
- 每个新实例都有父类构造函数的副本,臃肿
- 【原因】子类构造函数中产生了闭包,闭包导致内存泄露
- 无法继承父类原型上的属性
- 【原因】如图(3)
- 无法实现父类构造函数的复用