js构造函数、原型、原型链
前言
在js学习过程中,总有几个稍微难一点的东西使大家摸不着头脑,其中原型、原型链就是一点,但是在学习原型的前提下必须要搞懂构造函数这个知识,这些东西是联系在一起的!
构造函数
定义
用
new
关键字来调用的函数,称为构造函数。构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋予初始值,构造函数首字母一般
大写
为什么要使用
在做项目过程中,你可能想要添加多条数据,如果我们一条条的去添加未免有点麻烦,例如:
let one ={name:'james',age:37,positions:'SF'}let two ={name:'davis',age:29,positions:'PF'}let three ={name:'curry',age:33,positions:'SG'}let four ={name:'George',age:31,positions:'PG'}let five ={name:'Jokic',age:27,positions:'C'}.....
我在这里要录入nba球员的数据,我如果采取这种形式,我只能一条条的去写,其中,name、age、positions属性我要一直去填写,我一想,nba里面有几百名球员,我要是一直这样录,我不得累死?这时,
构造函数
的便利便显示出来了!
我们可以将name、age、positions作为构造函数的
参数
,代码示例如下:
functionPlayer(name,age,positions){this.name = name,this.age = age,this.positions = positions,this.play=function(){
console.log('我打球很厉害!');}}
当我们创建构造函数后,我们便可以通过new关键字去调用了:
let a =newPlayer('james',37,'SF')let b =newPlayer('davis',29,'PF')let c =newPlayer('curry',33,'SG')...
我们能够发现这一种方式非常的方便,能够大幅度减少我们写重复代码,这就是构造函数的
代码复用
执行顺序(new执行)
- 在内存中创建一个新的空对象
- 让this指向这个空对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象(注:
所以构造函数里面不用写return
)
原型对象(prototype)
构造函数虽然好用,但是也存在一个问题,那就是
浪费内存
在使用构造函数创建对象时,如果对象里面有方法(
复杂数据类型
),需要单独开辟
内存空间
那么我们创建多个对象时,不仅要为这些对象创建
内存空间
,还要为每个对象创建单独的
内存空间
,这就造成了
内存浪费
,所以,我们引进了
原型
!
构造函数通过
原型
分配的函数是
所有对象
所
共享的
Javascript规定,
每一个构造函数都有一个prototype属性
,指向另一个对象,注意:这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有.
我们可以将哪些不变的方法
,直接定义在prototype对象上,这样,所有对象的实例就可以共享这些方法.
functionPlayer(name,age,positions){this.name = name,this.age = age,this.positions = positions
// this.play = function() {// console.log('我打球很厉害!');// }}Player.prototype.play=function(){
console.log('我打球很厉害!');}let a =newPlayer('james',37,'SF')let b =newPlayer('davis',29,'PF')let c =newPlayer('curry',33,'SG')
a.play()//我打球很厉害!
b.play()//我打球很厉害!
由此,一般情况下
公共的属性
定义到
构造函数
中,
公共的方法
定义到
原型对象
中,原型可以解决
内存浪费
的问题,不用每次再单独开发一个内存空间,只用开发一个即可,将所有对象指向原型对象就可以了!
对象原型(_ _proto _ _)
每个对象都会有一个属性
__proto__
,指向构造函数的
prototype原型对象
,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在
console.log(a)
这里我们打印了一下对象a:
我们会发现
__proto__
指向了我们的构造函数的原型对象
Player.prototype
我们可以做一个测试:
console.log(a.__proto__ ===Player.prototype);//true
控制台打印的是
true
,因此断定,
__proto__
指向了构造函数原型对象
方法查找规则
首先看对象a身上是否有play方法,如果有就执行这个对象身上的play
如果没有play这个方法,因为有__proto__的存在,就去构造函数原型对象prototype身上去找play这个方法
原型链
既然了解了原型,那么原型链理解着也相当容易,我们知道
__proto__
指向构造函数的原型对象,那么有没有考虑到构造函数的原型对象的原型是谁呢?我们先来打印一下:
console.log(Player.prototype.__proto__ ===Object.prototype);//true
打印出结果为
true
,所以我们得出
构造函数的原型对象的原型是:Object.prototype
,由此我们继续寻找
Object.prototype.__proto__
,结果打印出是
null
。
这种一次向上寻找的过程形成了一个
链
,这就是原型链
这个图为原型链的描述,图中的
constructor
是指向构造函数的意思.
小结
在前端面试的过程中,面试必问的基础知识点就是原型和原型链,因此必须要去深入理解,并去掌握它,主要是搞懂它们的实现原理,实现的过程,希望大家能够打好js基础,
基础不牢,地动山摇!
版权归原作者 前端小白在前进 所有, 如有侵权,请联系我们删除。