前面写了很多关于前端经验之谈,今天就来点干货吧。这篇文章将会介绍原型这个概念
原型是整个Javascript中比较重要的概念,如果面向对象想要学好,那么这个东西你必须要了解,不然后面的原型链,继承,多态,设计模式你根本没得完。
但是很多人,尤其是自学的人,可能翻阅了各种资料,说不定也看过不少人的博客吧,我这篇文章可能你可能会懂,也可能看不懂。那也没办法,本身这个了解概念的过程本身就是最难也是最没有耐心干的一件事情。所以我尽量讲这篇文章写的通俗易懂,忘大家理解。
首先,原型是指构造函数中的一个属性,叫做prototype。这个属性常常被用来对构造函数方法的扩展;
//构造函数fn funtion fn(){} //为构造函数添加一个实例方法 fn.c.show = function(){ console.log("这是一个实例方法"); } //实例化一个foo对象 var foo = new fn(); //调用原型方法 foo.show();//这是一个实例方法
看到这里,可能很多同学会发现,这个原型方法其实也可以在实例化之后自定义一个方法
function fn(){} var foo = new fn(); foo.show = function(){ console.log("这是一个自定义方法"); } foo.show();//这是一个自定义方法
这当然可以,从语法上也是没有错的。但是,站在面向对象的角度去考虑,我们是要先构建一个构造函数,这个函数也就是我们平时玩游戏创建人物的过程,在这个过程中,这个人物是没有创建的。也就是说,这个人物实例是不存在的。那么原型的意义体现出来了。它可以在你构造阶段就可以添加方法,包括杀怪,升级这些功能都可以在这里扩展的,等我设置人物属性方法完毕以后我们点击创建角色,是不是就有一个人物对象存在啦。这样一比喻,脑袋里面有没有一点模样出来了呢!呵呵!
那么什么又是原型链了,首先你得知道这个属性,叫做_proto_;
这个属性是隐式的,所以我们是无法访问的。所以各位小伙伴你去访问的时候肯定是underfind。
不过没关系,既然这个东西存在我还是要说明下。这个属性是属于实例对象的。也就是上面例子中foo才拥有的属性,而且只要是对象,都会拥有这个属性的。
foo._proto_指向的谁了。是构造函数的原型方法,也就是fn.prototype。那么之前我说过,只要是对象都有._proto_属性,那么fn.prototype返回的是一个对象还是其他的?没关系,我们可以实验一下
typeof fn.protototype //object
这就有意思了,那么fn.protototype的_proto_属性又指向谁了?如果你有父类,那么就指向父类的原型,那么父类的原型又指向谁了?这个反复直到Object对象的原型属性为止,这一个过程就构成了我们的原型链,一整条关系链。而这个关系的核心就是我们的原型;
不知道这么讲你懂了没有。我当初就是这么去理解的,一开始肯定很懵逼,但是把思路理清楚还是有点头绪的吧。
foo._proto_ >> fn.prototype fn.prototype._proto_ >> Object.protottype //Object的原型是整个原型链的最顶端