## JavaScript之原型和原型链
在JavaScript的学习过程中,原型链肯定是一个很重要的知识点,下面我们就来深入的去看一下原型链
原型
首先看一个很简单的例子
1 | function Person(name, age) { |
控制台输出的是,和大多数人预想的一样,输出了两个person的年龄和姓名
在这个过程中我们创建了两个实例对象(person1,person2),有一个构造函数(Person)和原型(Person.prototype),那么他们之间的关系应该是这样的
在这里插入图片描述
在这个关系上我们可以看出
- 每个函数上面都有一个属性(prototype)指向了函数的原型对象(Person.prototype)。
- 每个实例上面都有一个隐式原型(proto)指向了函数的原型对象,如本利的p1对象有一个隐式原型也指向了Person.prototype对象。
- 每个函数的原型对象上面都有一个constructor属性,指向了构造函数本身。
实例的(person1,person2)的__proto__
也是Person.prototype
那么在实例访问属性或者方法的时候应该遵循什么样的原则?
- 如果实例上面存在,就用实例本身的属性和方法。
- 如果实例上面不存在,就会顺着
__proto__
的指向一直往上查找,找到就停止,找不到就报错。
1 | function Person(name, age) { |
那么输出的结果就是
如果找不到这个方法,就报错
在这里插入图片描述
虽然person1和person2都输出了sayAge方法,可是这两个方法是不一样的
原型链
那么在刚刚这个输出sayAge过程大概可以这样描述:
在person1上有sayAge,所以输出的就是person1上的sayAge
在person2上没有sayAge,但是在person2的原型上有sayAge,所以输出的就是person2上的sayAge
简单点说就是,如果我自己有,我就用我自己的;如果我没有,则去我的上一级找;这样就形成了一条原型链。上一节中Person的原型其实还有一属性__proto__
,他指向了上一级Object的原型对象。
Object.prototype可以说是原型中的最高层,那么最终原型链应该是这样的
原型和实例之间的判断
使用instanceof
1
2console.log(person1 instanceof Person)//true
console.log(person1 instanceof Object)//true使用isPrototypeOf()方法
1
2
3console.log(Object.prototype.isPrototypeOf(person1))//true
console.log(Person.prototype.isPrototypeOf(person1))//true
console.log(Function.prototype.isPrototypeOf(person1))//false
在ES6中的新运用
在ES6中,新运用了class来对JavaScript的语法更加加以完善。
在其他语言中,例如java,就有类(class),里面有构造函数(constructor),属性,方法等
所以在ES6中,为了弥补之前的不足,新推出了class
在以前的js中,生成一个对象实例,需要先定义构造函数,然后通过prototype 的方式来添加方法,再生成实例,但是现在ES6可以这样写
1 | class Person{ |
在ES5中原本的构造函数被constructor 替代,本来需要定义在prototype上面的,方法直接定义在class里面即可。
继承
在ES6中可以使用extends来继承类(和java差不多)
1 | class Student extends Person{ |
在ES5中prototype的继承
1 | function Person(age,name) { |
在ES6语法上更加便捷