• javascript之一切皆为对象3


    在前面两个章节“Javascript之一切皆为对象1”和“Javascript之一切皆为对象2”中,曾提到:

    1、“一切(引用类型)皆为对象”

    2、 “每个函数都有一个prototype”

    3、 “每个对象都有一个__proto__”

    那么,问题来了,在随笔“Javascript之一切皆为对象2”中,不是有下图么

    那,根据“一切(引用类型)皆为对象”,图中的函数Fn不也是对象吗?

    那它也有__proto__,那么它是指向谁的呢?!!

    答案:Function.prototype

    为什么这么说呢?

    因为函数Fn不是通过Function创建的么

    所以Fn.__proto__指向的是Function.prototype。

    不信?

    我们一起写个demo并运行代码,证实下。打开chrome调试器截图如下。

    <!DOCTYPE html>
        <head>
            <title>ttt</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </head>
        <body>
            <script>
                //创建一个Fn函数
                function Fn(){}
                //打印Fn的隐指针,即Fn.__proto__
                console.log(Fn.__proto__);
            </script>
        </body>
    </html>
    View Code

    我靠,这是什么鬼!!

    我只想说,应该是浏览器(我的chrome浏览器版本是48)还不支持Function.prototype吧。

    那,怎么证明你上面所说的Fn.__proto__指向的是Function.prototype呢?

    这样,我们知道prototype有个属性constructor吧,它是指向函数本身的,所以呢,倘若Fn.__proto__指向的是Function.prototype,那么Fn.__proto__.constructor就是指向的Function咯。

    所以只要我们验证Fn.__proto__.constructor指向的是Function,那么就可以得出Fn.__proto__指向的是Function.prototype了哈。

    demo和chrome截图如下

    <!DOCTYPE html>
        <head>
            <title>ttt</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </head>
        <body>
            <script>
                //创建一个Fn函数
                function Fn(){}
                /*首先调用Fn的隐指针(__proto__),
                  然后再通过Fn.__proto__的constructor看看它指向的是什么
                */
                console.log(Fn.__proto__.constructor);
            </script>
        </body>
    </html>
    View Code

    哈哈,从上面的截图可以看出Fn.__proto__.constructor的确指向的是Function,所以这会信了吧,Fn.__proto__指向的是Function.prototype。

    所以修改上面的流程图,得下(为了结构更加清晰,我们将上图中的fn1对象删除,只留一个fn对象):

    咦,看了改造后的流程图,有个疑问,Function不也是个对象么,那它的__proto__指向谁呢?

    答案:它自己的prototype。

    何出此言?

    因为Function也是个函数,所以它一定是被Function创建的,即它自身,因此,它的__proto__指向的是Function.prototype。

    在上面,我们知道了Fn.__proto__.constructor是指向的Function的,那么倘若要证实Function.__proto__是指向的Function.prototype,只要Function.__proto__.constructor指向的是Function就欧克啦,即Fn.__proto__.constructor.__proto__.constructor指向的是Function。

    代码和截图如下:

    <!DOCTYPE html>
        <head>
            <title>ttt</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </head>
        <body>
            <script>
                //创建一个Fn函数
                function Fn(){}
                console.log(Fn.__proto__.constructor.__proto__.constructor);
            </script>
        </body>
    </html>
    View Code

    看来Function.__proto__的确是指向的Function.prototype。

    根据Javascript 之一切皆为对象2中,提到prototype也是对象,所以Function.prototype也有__proto__,且指向的是Object.prototype。

    从上面,我们知道Fn.__proto__指向的是Function.prototype,所以我们检查Function.prototype.__proto__是不是指向的Object.prototype,也就是看看Fn.__proto__.__proto__是不是指向的Object.prototype咯。

    验证代码和截图如下:

    <!DOCTYPE html>
        <head>
            <title>ttt</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </head>
        <body>
            <script>
                //创建一个Fn函数
                function Fn(){}
                console.log(Fn.__proto__.__proto__);
            </script>
        </body>
    </html>
    View Code

    验证完毕:Function.prototype.__proto__指向的是Object.prototype。

    所以,再次改造上图,得下流程图:

     

    咦,从上图看到Object不也是对象吗?那它的__proto__指向谁呢?并且它的prototype的__proto__又指向谁呢?

    答案:Object当然也是Function创建的,所以它的__proto__指向的肯定就是Function.prototype咯。由于Object.prototype是最后一个链,所以它(Object.prototype)的__proto__指向的就是null。

    Object是函数嘛,它的__proto__指向Function.prototype倒好理解。

    但,你说Object.prototype的__proto__指向的是null?!!

    是的,Object.prototype.__proto__指向的是null,代码和截图如下:

    <!DOCTYPE html>
        <head>
            <title>ttt</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </head>
        <body>
            <script>
                //创建一个对象obj
                var obj = new Object();
                /*obj.__proto__指向的是Object.prototype,
                  所以,obj.__proto__.__proto__就是Object.prototype.__proto__
                */
                console.log(obj.__proto__.__proto__);
            </script>
        </body>
    </html>
    View Code

    嘻嘻,对的吧。

    再次改造上图,得下效果图:

     

    好了,如果你能理解以上这张图,恭喜你,原型链的流程也估计差不多理解咯。

    如果喜欢本文,请点击右下角的推荐哦,谢谢~
    更多,见My微信公众号^.^
  • 相关阅读:
    AGC 044 A
    example
    python3遇到的问题
    构建开发环境
    pandas处理数据
    pandas.DataFrame对象解析
    pandas再次学习
    监督式学习
    机器学习的基础概念
    赖世雄老师的音标课,旋元佑老师的语法书
  • 原文地址:https://www.cnblogs.com/giggle/p/5205602.html
Copyright © 2020-2023  润新知