zoukankan      html  css  js  c++  java
  • Javascript之旅——第十一站:原型也不好理解?

     

    写到这篇,我的js系列也快接近尾声了,所以这个系列不会遗留js来实现面向对象的核心——原型,有些人说原型不好理解,其实嘛,要想系统的理解原型,最便捷的方式就是看看经典的书,少看些博客,博客这东西只是博主自己的个人理解,充其量是些配味的佐料。

    一:继承

    如果你熟悉C#的话,你肯定会知道,所有的类都是继承于Object的,这样我就拥有Object所具有的功能了,如下图中我定义的Person类。

    从图中可以看到,在C#中到处都是继承,下一步我要做的就是自定义继承,如下图中我定义的Student类,让它继承Person.Name属性。

    这些对于玩C#的人来说都是很司通见惯的,那么下一个问题来了,这些真正的面向对象的东西,在js中该怎么玩呢?当然就要用到大名鼎鼎的prototype属性了。

    二:用JS来模仿C#的继承

    1.默认继承Object

    我们都知道在js中的所有引用类型也同样继承于Object,这样也就具有Object的功能了,但是你有没有考虑过,比如下图中的Person到底是怎么继承了Object的所有属性和方法呢?

    看到上图后,你是不是很好奇呢?其实原理真的很简单,用chorme的watch expressions一看你就一清二楚了。

    第一眼看到不知道你会不会眼晕?听我慢慢解释,从上面的图中不难看到,其实有这么个原型链的关系:

    p.__proto__ =Person.prototype

    Person.prototype.__proto__ -> new Object()

    不知道你看懂了没?其实这里最重要的就是__proto__属性,首先你要知道,每个实例都具有这么个__proto__属性,因为这是核心,比如你要找p.toString()方法, js引擎会优先在Person function中找toString()方法,发现没有。。。花擦。。。没辙只能通过p.__proto__属性继续往上查找,到了Person.prototype,从图中可以看到prototype是一个具有constructor属性的对象,因为只有一个属性,所以也没找到tostirng()方法,然后沿着Person.prototype._proto__找到了Object,在这里我们就找到了toString()方法。

    2.自定义继承

    我们知道prototype是个非常重要的属性,为了模仿C#中Student类继承于Person类,这次我需要做的是让Studnet.prototype=new Person()就好了。

    从图中可以看到student实例已经含有Name属性了,我们现在已经知道有一个原型链查找的过程,比如我现在通过student.__proto__找到了new Person(),然后也看到了new Person()具有Name属性,我想你现在也知道,在Person函数中也有一个__proto__属性,它是指向Object的,如果说我在new Person()中没有找到,那么会继续通过Person.__proto__(Student.prototype.proto__)继续往上找,一直找到顶端为止。

    三:详解prototype

    1. prototype到底是什么?

    从上一章中我想你对prototype应该有了宏观了解,可以看到其实prototype只不过是一个包含constructor属性的Object对象,其中constructor属性是指向当前function的一个指针,代码还原如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <script type="text/javascript">
            function Person() {
                this.Name = "ctrip";
            }
     
            Person.prototype = {
                constructor: Person  //指向Person的constructor
            };
     
            var p = new Person();
        </script>

    2. prototype上面的属性可以被所有实例共享。

    这个之所以能够共享,是因为每个实例都有__proto__属性,包括function的prototype属性也是有__proto__属性的,这是因为prototype本质上也是一个对象的实例,所以js在查找某个属性是否存在的时候会通过__proto__属性一直追踪到object。

    3. 如果function中的属性与prototype属性冲突了怎么办?

    看到答案后,我想你也非常清楚了,毕竟你已经理解了原型链的查找,因为js引擎查找过程是先从本函数查找,如果找到就return,找不到继续通过__proto__往上找,很好理解的。


    原文出处: 一线码农的博客   欢迎分享原创到伯乐头条

  • 相关阅读:
    【转载】opencvVS2019配置方法
    windows.h头文件中改变光标位置的函数——SetConsoleCursorPosition
    五行代码解决猴子选大王问题
    AtCoder Beginner Contest 192
    ACM做题注意事项
    数据库部分重点
    数据库7-11章期末复习
    数据库4-6章期末复习
    数据库1-3章期末复习
    ICPC Central Russia Regional Contest (CRRC 19)
  • 原文地址:https://www.cnblogs.com/sunscheung/p/4342162.html
Copyright © 2011-2022 走看看