之前有在自己的文章中谈到对象,而说到对象我们就不可避免的要扯到原型,并且原型也是我们必须得理解到位的一个点,那接下来我们就来聊一聊js的原型吧。
JS中一切皆为对象,那么原型也是一种对象。所以它有对象的特性,无非也是一系列无序键值对的集合,接着我们就来具体看看吧
function person(name,age)
{
this.name=name;
this.age=age;
}
var a=typeof person.prototype//object
var b=typeof person.prototype.constructor//function
var c=person.prototype.constructor==person//true
我们可以看到我们创建了一个构造函数person,通过prototype找到了原型对象,我们可以看到以下几点
- 用typeof可以看到原型确实是一个对象
- 这个对象有一个constructor属性,属性值是function
- 这个function就等于构造函数person
此处我们首先可以明确了构造函数和原型对象的关系了吧
接着我们再来看看原型和构造函数创建的对象的关系
function person(name,age)
{
this.name=name;
this.age=age;
}
var pengl=new person("pengl",100);
var flag=person.prototype.constructor==pengl.constructor;//true
我们依然可以看到新建对象的构造函数就是原型对象的构造函数。
本质:原型对象中的原型两字是对谁的原型,实际上是对于新建的这些对象的原型,是这些对象中那些不变的,共有的东西,比如构造函数,各个对象的区别只是在于通过构造函数新建该对象时,传入的参数不同。而像构造函数或者一些其他建立在原型上的方法和属性都是属于原型级别的,只是新建的对象作为它的具体实例可以用而已。
我们可以从这样一个角度来理解
function person(name,age)
{
this.name=name;
this.age=age;
this.func=objFunc;
function objFunc (argument) {
alert("我是属于新建对象的方法")
}
}
var pengl=new person("pengl",100);
pengl.func();
另一段代码
function person(name,age)
{
this.name=name;
this.age=age;
}
person.prototype.func=function (argument) {
alert("我是属于新建对象原型上的方法")
}
var pengl=new person("pengl",100);
pengl.func();
第一段和第二段的区别就是是否把func方法创建在构造函数中,第一段就是直接在新建对象的级别上创建了一个方法,第二段是在新建对象的原型上创建的方法。从内存的角度看,对于第一段每创建一个对象,就要同时再创建一个func方法,而第二段是,无论创建多少个对象,都只需要一个func方法,这个方法是所有对象所共有的。
最后我们就要引出原型链了
从原型链的链字我们就可以猜到大概是什么意思,比如我们使用一个方法,先从该对象上找,如果没有那么就从该对象的原型上找,如果该原型没有,就从该原型的原型上找,以此类推。如果最后都没找到,则返回undefined
上面例子中的原型链:
pengL->person.prototype->object.prototype->null
至此原型就到此为止啦,我们最后进行一下总结吧
- 原型是对象
- 原型包含了新建对象的各种共有的方法和属性
- 使用对象的方法或属性流程是:先从该对象找,没有则从它的原型上找,再没有,就从原型的原型上找,以此类推