zoukankan      html  css  js  c++  java
  • JS中的prototype和__proto__

    Prototype

    在JS中,每一个函数都有一个prototype属性,它的作用,简单的理解,就是当使用new关键字实例化一个函数的时候,这个函数prototype里面的对象也会共享到新实例里面。

    function M1(){
        name:'john'
    }
    M1.prototype.sex = 'male'
    M1.age = 18
    var m2 = new M1()
    console.log(m2.name)//undefined
    console.log(m2.sex)//male,因为sex在M1的prototype中,所以new出来的m2可以访问这个属性
    console.log(m2.age)//undefined
    

    其中,

    M1.prototype.sex = 'male'
    

    在M1的prototype属性中定义了sex,值是male,那么new M1()得到的实例m2,也具有了sex,并且值是male

    由于age属性没有定义在prototype上,所以m2无法访问。

    M1.prototype.sex和M1.sex是不一样的,接着上面的代码:

    M1.sex = 'female'
    
    console.log(M1.sex);//female
    console.log(M1.prototype.sex);//male,可以看出M1.prototype.sex和M1.sex不是一个对象

    查看运行时值更直观一些

    可以看到有两个sex,一个是M1属性,一个是M1.prototype属性。从上面可以看出,prototype其实是一个对象。

    当m2=new M1()的时候,并不是把M1.prototype的内容复制一份,而是m2具有了一个指向M1.prototype的“指针”,所以修改M1.prototype,也会使m2的对应值变化。

    下面验证一下修改M1.prototype,m2也会变化,但是修改m2的对应属性,M1.prototype不会变化

    M1.prototype.sex = 'unknown'
    
    console.log(m2.sex)//unknow,修改了M1.prototype.sex,m2实例中的值也会改变
    m2.sex = 'female'
    console.log(m2.sex)//female
    console.log(M1.prototype.sex)//unknown,修改m2.sex,M1.prototype对应的值不会变化

    既然是“指针”,为什么修改m2.sex,没有改变M1.prototype.sex呢,看一下运行值就知道了


    执行m2.sex='female'后,修改的并不是prototype部分,而是新建了一个属性m2.sex。如果要使M1.prototype.sex也变化,使用m2.__proto__.sex就可以

    m2.__proto__.sex='female'
    console.log(M1.prototype.sex);//female

    __prototype

    __proto__是一个“指针”,它“指向”一个对象,上面的例子中,m2=new M1(),那么m2会自动具有__proto__=M1.prototype。也可以手动修改__proto__,使它指向别的对象。

    function M1(){
        name:'john'
    }
    var m2 = new M1()
    m2.__proto__=M1
    M1.sex = 'male'
    console.log(m2.sex)//male

    可以看到,sex直接定义在了M1上,而没在prototype中,m2仍然可以访问了。这是因为我们改写了__proto__,直接指向了M1对象。
    __proto__不是js的标准规范里面的规定,各主流js引擎都支持,但不建议直接使用。

  • 相关阅读:
    Oracle Redo 并行机制
    ORA16032 Can not Start Instance via srvctl but via sqlplus is fine [ID 1062071.1]
    Linux 各文件夹的作用
    Private strand flush not complete 说明
    Executing root.sh errors with "Failed To Upgrade Oracle Cluster Registry Configuration" [ID 466673.1]
    openfiler 搭建虚拟存储 并 配置服务端
    Oracle RAC CRS0184 Cannot communicate with the CRS daemon
    Redhat 5.4 RAC multipath 配置raw,运行root.sh 时报错Failed to upgrade Oracle Cluster Registry configuration 解决方法
    Openfiler + Redhat 5.4 Oracle 11gR2 RAC 安装文档
    How to Troubleshoot Grid Infrastructure Startup Issues [ID 1050908.1]
  • 原文地址:https://www.cnblogs.com/wangguanguo/p/8203366.html
Copyright © 2011-2022 走看看