简单理解js的prototype属性

  在进入正文以前,我得先说说我认识js的prototype这个东西的曲折过程。html

  百度js的prototype的文章,先看看,W3School关于prototype的介绍:数组

  

 

    你以为这概念适合定义js的prototype这个东西吗?你是否也认为prototype是一个object对象的属性呢?是的话,请认真认真看我这篇文章,由于这篇文章会毁灭你的人生三观,呵呵,就是有这么严重,由于本人就是被这个定义给害惨的。函数

    不得不说,看了网上的一些介绍prototype的文章,基本上都说prototype是对象的一个属性,因而,我也坚决的认为prototype是一个对象的属性,因此,我被了坑很久很久,由此,引起的后果就是,我一次次的误解别人写的含有prototype的js代码,也就是当别人亮出js的prototype这个属性来写js代码时,我看着他们写的代码都是 ····一头雾水·····  ,悲催啊!因此,我恨死prototype这个东西了,所以,在这里,我今天必须把js的prototype属性道个明明白白。看官,请擦亮你的眼睛,仔细看我下面的实验。测试

    固然,我但愿诸位看官也可以静下心来,把我下面的实验从新作一遍,好证实个人结论是正确的。spa

    同时,也为了证实·····我没有····骗大家·····,呵呵,废话很少说了,下面进入实验阶段。prototype

    先介绍一个下面要用到的函数,JSON.stringify(value)。3d

    这个函数的做用是:把传入的参数value变成字符串,它有三个参数,第一个参数是必须的,其他的两个参数可填可不填。code

    关于JSON.stringify函数的做用请看这篇文章。http://www.cnblogs.com/ningvsban/p/3660654.html,这里说的很清楚。htm

    首先,测试W3Schol的定义到底行不行的通:对象

    若是,真如W3Schol所说的那样,prototype是object的一个属性,那么,咱们来建立一个对象,看看这个对象的prototype究竟是啥。

var ob = { };//超级简单的空对象
alert(JSON.stringify(ob.prototype));

 

    你以为上面的代码会alert出什么呢?既然prototype是object的一个属性,那么上面确定可以获取到什么东西对吧?可是,若是你拿这段代码去作实验了,你会被打脸的,由于它alert的东西是·········undefined··········,也就是说object这个属性prototype不是个东西,很残酷吧,但现实就是这样,任何对象引用prototype都会出现undefined,不信,你能够试一试。

    我能够很明白的告诉你,prototype绝对不是给对象用的,对象根本没办法引用prototype这个属性,它真正的属主,实际上是···········函数········,记住,可以引用prototype的东西绝对是函数,绝对是函数,绝对是函数,prototype是属于函数的一个属性,prototype是属于函数的一个属性,prototype是属于函数的一个属性,可以引用它的只有·····函数····,可以引用它的只有·····函数·····,可以引用它的只有····函数····,函数,函数,函数,重要的事情必定要说千百遍,呵呵,由于只有明确这一点,下面,你才明白我要讲的东西。别怪我这么墨迹啊!

    下面,我要给prototype一个名副其实的定义:

    prototype是函数的一个属性,是函数的原型对象。

    就是这么简单,能看明白吗? prototype只可以被   函数     调用。

    别搞混了js的object对象和function函数,js的对象和函数绝对是两个概念,为何?由于js的function函数能够new出object对象啊,是吧?这个你总该知道吧?

    下面,来作试验证实个人结论。   

//首先定义一个有名函数func
function func(){ } alert(func.prototype);

    你说,上面的代码会alert什么呢?还会不会是undefined的呢?我敢确定的告诉你绝对不是undefined的,由于本人已经alert过了,呵呵。

    上面,弹出的窗口是:

     没错,返回的就是对象,这回你肯相信我,可以调用prototype的必定是函数了吧?object引用prototype的时候给你返回的是一个不是东西的东西undefined,函数引用prototype的时候给你返回一个真真实实存在的东西object的,这还不够证实prototype是给函数用的吗?还不可以证实对象是不能引用prototype的吗?呵呵,又多说了。

    上面我已经说过,prototype是函数的一个属性,也是函数的原型对象,而这里func函数引用prototype的时候返回的是一个对象object的,那么,结合这两个概念,你能得出什么结论呢?我想经过这不可贵出结论:

    prototype是········函数的原型对象············,这能理解吗?不能理解,没有关系,咱们再来作一个实验,终于要用到文章开始给大家介绍的一个函数JSON.stringify()了。

function func(){ } alert(JSON.stringify(func.prototype));

    仍是引用上面的函数func,只不过这里返回的是JSON.stringify()函数的返回值。

   你没有看错,这里alert的结果是一个空对象,这证实,prototype的的确确属于函数的属性,而且函数的prototype属性的js数据类型是对象,明白不?为何如今是一个空对象?你有没有想过?为何呢?请思考这个问题三秒钟,假如想不出来,那么没有关系,下面,我来解释。

  先看,实验代码:

function func(){ } func.prototype.name ='prototype是函数的的属性,本质是函数的原型对象'; alert(JSON.stringify(func.prototype))

    你说,上面的代码会alert出什么呢?请看下面:

     你没有看错,此刻,终于alert出东西来了,我在这里给prototype赋于一个属性name,因此,我这个时候在alert函数func的prototype时,你看到有值了吗?看到了prototype的属性name值了吗?如今再想一想,为何上面第一层alert函数func.prototype的时候,它是一个空对象呢?而如今它又是一个有值的对象呢?

    缘由很简单呢,由于第一次的时候,我没有给函数的属性func.prototype赋予name属性,也没有给name属性赋值啊,而如今我已经给函数的属性func.prototype赋予属性name,而且赋值为········prototype是函数的的属性,本质是函数的原型对象······,因此,如今alert函数的属性func.prototype的时候它就有值啦,对吧?

    所以,这里得出结论:

    prototype是函数的的属性,本质是函数的原型对象。

    别觉得js中只有对象才有属性,经过这里,咱们也能够知道,其实js的函数也是有属性的,并且js的函数好像就只有这个属性prototype,并且js的这个函数属性同时仍是函数的原型对象,你是否是被搞晕了?但愿你没有被搞晕才好。

    为何说prototype是函数的一个属性呢?由于,只有函数才能调用prototype,并且是以这样的方式func.prototype调用的,这样的方式调用东西是否是和对象调用属性如出一辙呢?是的,就是由于函数调用prototype的时候是和对象调用属性的时候同样的,咱们才把prototype说成是函数的一个属性,而函数的这个属性实际上是一个对象(这个是否是对象,上面已经证实了,这里就再也不说明),因此说,这个prototype就是函数的属性,本质是函数的原型对象。

    这里为何强调说prototype的本质是函数的原型对象呢?

    下面看代码证实,个人代码很简单的:

    //定义一个函数
    function func(){ } //给函数的属性prototype赋予一个方法get
    func.prototype.get=function(value){ return value;//很简单,你给我什么我就输出什么
    }

    你说,怎么调用上面那个get方法?

    我给你一点提示,get是属于func函数的一个属性函数,既然是属性函数,那么咱们怎么调用呢?

    很简单,属性函数必须由它的对象来调用,那么咱们怎么获取get的对象呢?很简单,用关键字new来实例化func函数的对象就好了吗?是吧?

    下面,实例化func函数的一个对象ob1:

var ob1 = new func();
//用func实例化出来的对象来调用get属性函数
alert(ob1.get('hello,prototype原型对象'));

    没错,用func函数实例化出来的对象ob1,确实可以调用get函数,上面已经利用ob1调用get函数alert出来了,这就证实func函数的实例对象是拥有get这个属性函数的,对吧?这么明显,就不用说明了吧。

    若是,你不信必需要用实例化func的对象来调用get函数,你能够试试直接用func调用get函数,也就是说,你能够尝试着func.get()调用一下get函数看看,看func它到底能不可以直接调用get函数。我想必定报错,呵呵,缘由是什么,你本身想。

    那么,说了这么多,我仍是没有说明,为何我说prototype的本质是函数的原型对象啊?对吧?

    请看,下面的代码:

 

var ob2 = new func();
//用func实例化出来的对象来调用get属性方法
alert(ob2.get('我依然是func实例化出来的对象'));

 

 

     看到没有,我仍是再次利用func函数实例化一个ob2,这个对象依然可以调用get属性函数,这说明什么了呢?这说明了,利用func对象实例化的全部对象均可以调用get这个属性函数。既然如此,你说,prototype这个属性若是不是函数func的原型对象的话,那么为何给prototype赋予的属性函数get可以被func全部实例化的对象所调用呢?假如prototype的本质不是func函数的原型对象,那么依据func函数实例化出来的对象就不可能一个个都可以调用get这个属性方法,对吧?为何?咱们来个比例,你说,一个不是源头的东西,它能影响到全部的东西吗?不可以吧?所以,这里得出结论:

    prototype是函数的一个属性,本质就是函数的原型对象。

    整篇文章就是为了说明这个结论。无他。但愿看官能看懂这篇文章。对于prototype的应用下篇文章再讲,在此打住。

       特别指出:

           Array.prototype是一个数组

       String.prototype是一个字符串

       Object.prototype是一个对象

           这三个特殊例子,不像构造函数的prototype同样。详情请看下一篇文章。

相关文章
相关标签/搜索