0%

原型与构造函数的继承


构造函数 与 原型 一直是继承的一个重点,原型也是javaScript的一个特色 , 今天和大家分享一下构造函数的继承,以及函数中原型的概念

原型的概念

在说构造函数之前,我们先来探讨一下我们之前博客中提到的原型, 什么是原型?

在JavaScript中,通过原型可以实现对象的属性继承,这时候就有一个问题,我们没有定义原型,原型是怎么来的?
之前说过,在H5中,一切皆为对象,所以函数也是一种对象,javascript默认的给函数一个属性——prototype。
这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor的属性,指向这个函数本身。

注意这个prototype属性,这是只有函数才拥有的,其他的对象也有原型使用的是(proto)

原型上填写共有的属性和方法

共有的属性和方法都放在原型里,这样不会占用太多的内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14

function Dog(name){
this.name = name;
}
//对这个构造函数的原型进行重新定义,把原来的去掉,注意:会把构造函数一起去掉
Dog.prototype = {
family:"金毛",
jiao:function (){
alert(this.name + '汪汪汪');
},
construction:Dog
//因为原型中缺少呢一个构造函数,所以我们自己加
}
//Dog.prototype.construction = Dog; 这样也可以添加构造函数

这样就实现了在原型上填写共有的属性和方法,当然,原型也有他自己的缺点:

修改一个地方,任何一个基于该构造函数的对象都会发生改变,所以原型不能进行值的传递

原型的小知识点

关于对象调用属性和方法的顺序,先在自身对象(构造函数)中去找,一直往上,找到直接调用;

isPrototypeOf() 判断原型和对象之间的关系
hasOwnProperty() 对象和属性,方法 之间是否存在关系,该属性,方法 必须是自身的(原型中的不算)

构造函数的继承

继承: 基类(父类)—->派生类,拓展类(子类)
特点: 不仅可以有自己的属性和方法,而且还可以拥有父类的所有属性和方法.并且可以增加自己新的属性和方法

构造函数的继承我把它称之为三步曲:

第一步:构造函数的继承
第二步:原型的继承
第三步:自身构造函数的创建

我们来看一个例子,假设我有个Animal这个类,并且我想让Dog类来继承它,应该怎么实现?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

//先创建一个构造函数(这个构造函数作为父类)
function Animal(family){
this.family = family;
}
//给构造函数的原型加入属性(为了验证子类是否可以继承父类)
Animal.prototype.leg =4;

function Dog(family,name){
//第一步:构造函数的继承(使用.call来继承构造函数)
Animal.call(this,family);
this.name = name; //这是声明子类私有的属性
}

//第二步:原型的继承,这里将Dog的原型全部替换成Animal的原型,注意:构造函数会被删除

Dog.prototype = Object.create(Animal.prototype);

/* Object.create(Animal.prototype)创建出来的是一个空的对象,并且空对象的原型是Animal的原型
所以我们就可以把空的对象作为Dog的原型 */

//第三步:Dog构造函数的创建
Dog.prototype.constructor = Dog;

到这里,就将原型和属性全部继承,在第一步中使用到的call,我简单的说明一下

apply 和 call方法的区别

call,apply都是属于function.prototype 的一个方法
call,apply 作用就是借用别人的方法来调用,就像在调用自己的方法一样

相同点:两个方法产生的作用是完全一样的
不同的:方法传递的参数不同

举个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

function print (a,b,c,d){
alert(a + b + c + d);
}

function example(a,b,c,d){

print.call(this,a,b,c,d);//用call方式借用print,参数是打散传递的

print.apply(this,arguments);
//用apply方式借用print,参数作为一个数组传递的,这里用的是JavaScript方法内本身有的arguments数组

print.apply(this,[a,b,c,d]);
//这样也可以
}

ES6的继承

现在来看看另外一种继承方式,ES6的继承

一、ES6的新继承方法

假设我有个People的父类,想要创建一个Man的子类去继承People

extends : 继承的关键字,这里相当于Man这个构造函数继承了People

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Man extends People{

constructor(name,age,sex){
// super : 就相当于会自动去执行 People 的构造函数,继承父类
super(name,age);

this.sex = sex;// 新增,扩展自己的属性
}

//这里是Man这个构造函数的新方法
playMJ(){
console.log(this.name + '正在运动');
}
}

var man = new Man('小黄',18,'男');//这里实例化的man,可以调用People的方法

ES6 的构造函数用法还是很简单的,注意extends 与 super 的用法

以上就是我对构造函数的继承及原型的一些理解,不足之处还望提出,感激不尽

-------------本文结束感谢您的阅读-------------
没办法,总要恰饭的嘛~~