zoukankan      html  css  js  c++  java
  • 对于JavaScript的__proto__以及prototype与constructor的理解。

    js是一门有趣的语音,最近一直在学习中,看了不少书籍。对于对象的一些内置特性了解的不好。

    这里写一些简单的笔记,方便自己的学习

    首先我自己的理解,这里面由三个对象,一个是实例,一个是构建函数,还有一个是原型。

    实例可以用过__proto__查看自己的原型或者用Object.getPrototypeOf这个命令查看,一样的效果

    function Demo(a){this.a = a}
    undefined
    var d = new Demo(99)
    undefined
    d.__proto__
    {constructor: ƒ}
    Object.getPrototypeOf(d)
    {constructor: ƒ}
    Demo.prototype
    {constructor: ƒ}
    

     从代码可以看出,实例可以通过__proto__查看自己的原型,这个原型可以理解为Python中的类?(也不是很对)

    后续通过原型给实例添加一些属性与方法,比较像Python中的猴子补丁。

    不光从实例可以看到原型,也可以通过构建函数查看原型,实例可以通过constructor查看构建函数。

    d.constructor === Demo
    true
    d.constructor
    ƒ Demo(a){this.a = a}
    Demo
    ƒ Demo(a){this.a = a}
    

     既然可以看到构建函数,我们通过构建函数查看一下原型

    Demo.prototype
    {constructor: ƒ}constructor: ƒ Demo(a)__proto__: Object
    d.__proto__
    {constructor: ƒ}constructor: ƒ Demo(a)__proto__: Object
    Demo.prototype === d.__proto__
    true
    

     通过演示,可以直接通过实例查看原型,也可以通过构建函数查看原型。原型有什么用,他可以在添加公用的属性与方法。

    Demo
    ƒ Demo(a){this.a = a}
    Demo.prototype.show = function(){console.log('show'+this.a)}
    ƒ (){console.log('show'+this.a)}
    d.show()
    VM8836:1 show99
    

     这里面肯定有人说,可以在构建函数的地方直接定义 添加这个对象属性。

    function Demo(a){
      this.a = a;
      this.show = function(){console.log('show'+this.a)}
    }
    

     但这样的话,会在每个新建的实例创建一个这个的方法,非常浪费内存空间。

    所以方法在原型中添加更加合适,为什么的话,看我下面分析

    function Demo(a){
      this.a = a;
      this.show = function(){console.log('show'+this.a)}
    }
    undefined    
    Demo.prototype
    {constructor: ƒ}constructor: ƒ Demo(a)__proto__: Object
    Demo.prototype.show
    undefined
    

     上面的代码可以看出在构建函数内通过prototype并不能查看到原型内的一些提供给实例的公用方法或者属性,

    其实也对,因为在构建函数里面定义的属性与方法每个实例都是特有的。

    所以这样的话,如果想使用构建函数内定义的方法会比较麻烦,只能通过实例来调用改方法。

    但如果通过原型的方式,给原型赋值属性并添加方法的方式,可以通过原型调用该方法,通过call、apply、bind的方式或者指定调用的方式来调用该方法,而且同样实例也能使用该方法。

    Demo.prototype.show = function(){return this.a + 'hello' + this.b}
    ƒ (){return this.a + 'hello' + this.b}
    d.show()
    "99helloundefined"
    Demo.prototype.show.call({a:888,b:'xxx'})
    "888helloxxx"
    var a = 'main'
    undefined
    var b = 'window'
    undefined
    var show = Demo.prototype.show  //赋值到全局变量组
    undefined
    show()
    "mainhellowindow"
    

    最后来看一下原型函数,通过constructor来获取,实例与原型的constructor调用都返回原型函数

    d.constructor === Demo
    true
    Demo.prototype.constructor ===Demo
    true
    

    最后是我前面碰到疑惑的,就是通过函数去调用__proto__获取构建函数的原型,以及constructor获取构建函数。

    Demo.__proto__
    ƒ () { [native code] }
    Demo.constructor
    ƒ Function() { [native code] }
    Demo.__proto__.parent_show = function(){console.log(this.a)}
    ƒ (){console.log(this.a)}
    

     通过__proto__可以查看到构建函数的原型,也可以通过构建函数给原型给构建函数添加共有属性方法,

    通过constructor可以看出构建函数的构建函数,正是Function函数。

    后续还有继承,下次有空再写笔记,继续主要通过__proto__查看上级的原型,实例继承该原型的属性以及方法。

    记住,任何一个函数都有prototype属性,这个属性是拿来给下级的实例调用的,所有的对象都继承或者实例来至Object函数

    所以Object中的原型属性,每个对象都会拥有。

  • 相关阅读:
    如果经常访问国外站
    CouchDB降临Android
    ubuntu server操作流程百岁版
    开源HTML解析工具包jsoup 1.3.1发布
    LEMP aka LNMP
    VC编译选项
    gae地址
    feedparser 同步博客园rss到 qq zone
    跨系统共享键盘鼠标利器分享:synergy
    支持ff,ie的回车提交
  • 原文地址:https://www.cnblogs.com/sidianok/p/13263130.html
Copyright © 2011-2022 走看看