• 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微信公众号^.^
  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/giggle/p/5205602.html
Copyright © 2020-2023  润新知