zoukankan      html  css  js  c++  java
  • 简单理解js的prototype属性

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

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

      

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

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

        当然,我希望诸位看官也能够静下心来,把我下面的实验重新做一遍,好证明我的结论是正确的。

        同时,也为了证明·····我没有····骗你们·····,呵呵,废话不多说了,下面进入实验阶段。

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

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

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

        首先,测试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一样。详情请看下一篇文章。

  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/huilixieqi/p/6496968.html
Copyright © 2011-2022 走看看