最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 不再云里雾里,让你深入理解JS原型链

    正文概述 掘金(巴扎嘿哟嘿)   2021-01-26   370

    当我们看原型的各种文章的时候, 你总是会看到 __proto__, prototype, construcotr, function, Object 这些关键字。 可能你看完了文章, 你以为你懂了, 其实。。你没有。。。。 我这篇文章就不去解析那些图了, 因为放上来看完也是一脸懵逼, 没有很直观。 我们就把这几个关键字理清楚,他们之间的各种关弄明白,那么原型和原型链这个东西 也就差不多明白了。

    __proto__

    __proto__, 这个东西在js中,每个对象都会有(null除外)。 不相信的现在打开console 试试看, 随便写一个 const test = 1, test.__proto__ 是有东西打印出来的。 那么大家会好奇,这个东西干嘛的,打印出来的是啥玩意。 这里先不过多的去解释, 先笼统的总结一下, 在我的理解中这个东西就是大家经常说的原型链的'链'。然后他‘链’的是个啥? 以上面的test 为例,test.__proto__ 指向的是创建test的类的 ‘prototpye’, 也就是我们所说的原型。 好了,下面我们就可以开始介绍prototype 这个玩意了。

    prototype

    prototype, 之前我看文章的时候以为只要是对象应该都有prototype这个东西。。。, 那其实是错误的. 那么js中哪些东西才有prototpye这个玩意呢? 总结一下: js中能拿来new的东西都有prototype, 带有prototype的对象是可以用来产生实例的。 我们现在来分析一下,  我们定义先定义个function

        function foo(name){
            this.name = name
           
        }
    

    这个写法其实也等于下面的写法

        let foo = new Function('name', 'this.name = name')
    

    那么按照上面说法 'test.__proto__ 指向的是创建test的类的'prototpye', 那么这里我们是不是可以判断 foo.__proto__ === Function.prototype 呢? 是的,大家可以试试。那么foo有没有prototype呢,大家可以在这里暂停一下好好想一想。。。。。, 答案是有的。 为什么,foo 是可以拿来new 的,用它去生产一个实例

        let bar = new foo('new instance')
    

    套用上面的理论: 能被拿来创建实例的对象是带有prototype的。然后我们可以判断出 bar.__proto__ === foo.prototype。 这里在抛出一个问题, bar 有没有prototype? 我想很多人已经知道了,没有. 因为我们无法通过bar 去new一个实例出来。 所以bar.prototype是unfedined。

        bar.__proto__ === foo.prototype
        foo.__proto__ === Function.prototype
    

    我们在来看看prototype里面都有什么,大家自己console打印一下会发现,里面有一个constructor属性,和__proto__, 前面说过了对象都会有__proto__ 属性的,prototype也不例外。 下面我们在说说constructor 这个东西

    constructor

    constructor, 我们称它构造函数。 这个东西是生成的prototype时候自动生成属性,它指向函数本身。 也就是说 foo.prototype.constructor === foo. 这里需要引入一个概念,'引用类型'(reference type)。 foo就是一个引用类型, 它指向的是内存中的一段地址, 而这个地址的位置存在的才是foo的具体的值。 那么foo.prototype.constructor 指向的也是这个地址,所以才会说prototype.constructor 指向的是函数本身,也就是foo. 然后foo它本身也是有constructor的。foo下的constructor指向的是创建foo的构造函数, 也就是Function, 所以 foo.constructor==== Function。 同理 bar.constructor === foo。 foo.constructor 是干嘛的, foo就是通过foo.constructor 创建出来的, 具体new的实现过程可以去自学下,这里就不阐述了。

    Object

    在这里我们要讲Object。我们打印出Object 会发现他有__proto__, 和prototype, 然后在展开Object.prototype 你会发现, 他下面是没有__proto__ , 这意味着什么,意味着原型链到这里就没有了, Object.prototype 就是原型链的源头, 万恶之源。

    懵逼了吗大家。懵逼了就先暂停下, 从头在看一遍, 理解消化了之后我们在往下走。

    实践 && 总结

    现在我们用上面总结的东西来实践一下,看看原型链是怎么个链法。

    function Person(){
        this.name = 'Tom'
       
    }
    const newPerson = new Person()
    

    我们知道 newPerson.__proto__ === Person.prototype, 然后我们打印一下 Perosn, 发现Person.prototype 的 __proto__ 指向的是Object。 也就是说 Person.prototype.__proto__ === Object.prototype。 我们之前提到Object.prototype 是原型链的尽头了, 也就是说我们这里得到了一条完整的原型链

    newPerson.__proto__ === Person.prototype
    Person.prototype.__proto__ === Object.prototype
    

    从而得到 newPerson.__proto__.__proto__ === Object.prototype 正常情况下我们想给newPerson添加一个属性,我们会这样操作 newPerson.age = 11. 但是其实我们也可以这样,把age添加到Object.prototype 上。 Object.prototype.birthday = '2010-09-27', 然后可以尝试打印 newPerson.birthday, 显示的就是'2010-09-27'。 为什么newPerson能访问到这个属性呢, 这就是因为原型链的关系。当我们尝试去访问birthday 的时候, 会在newPerson下找存不存在, 不存在就去newPerson 下的__proto__ 中去找(这个时候newPerson.__proto__ 指向是的Person.prototype)。 如果还没找到, 就在沿着newPerson.__proto__.__proto__去找(这个时候newPerson.__proto__.__proto__ 指向是的Object.prototype)。 然后我们在里面找到了birthday 这个属性,如何还没有就返回undefiend了, 因为已经路已经到头了。 再举一个例子。

    const c = 1
    c.toString()
    

    这个toString其实不是再c下面的,而是Object.prototype 下面。

    到这里原型链的作用我们可以总结一下了, 原型链可以让对象实现一个属性的共享和继承。 由构造函数生成的实例都可以访问构造函数原型中的方法和属性。 其实这里面还有东西没有讲, 那就是Function, 他比较特殊。放在这里一起讲怕到大家弄混淆了,如果大家感兴趣打算单独开一篇文章讲。 看到这里其实原型链的概念就差不多了,从原型链里面也可以延伸出很多其他的知识点, 比如new, this 等等。 以后会慢慢开始写,尽量通俗易懂的把这些讲清楚。


    起源地下载网 » 不再云里雾里,让你深入理解JS原型链

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元