zoukankan      html  css  js  c++  java
  • 一个示例捋顺JS原型链

    如果还不是很清楚JS原型链的小伙伴,可以把下面的代码运行一下,细细品味~

     1 // 1.构造函数
     2 function Dog(name){
     3   this.name = name
     4   this.action = function(msg){
     5     console.info(msg)
     6   }
     7 }
     8 
     9 // 2.使用构造函数Dog创建的实例对象
    10 var xiaohua = new Dog('小花')
    11 // 实例对象xiaohua可以使用构造函数中的属性、方法
    12 console.info(xiaohua.name) // 小花
    13 var xiaohei = new Dog('小黑')
    14 xiaohei.action('摇尾巴') // 摇尾巴
    15 
    16 // 3.直接使用构造函数中的方法,每个实例对象中方法都会复制一份,造成内存浪费
    17 // 如下两个实例对象相同的方法不相等
    18 console.info(xiaohua.action === xiaohei.action) // false
    19 
    20 // 4.使用原型
    21 // 每一个构造函数均有一个prototype属性,该属性是一个对象,其所有方法和属性都被构造函数所拥有,
    22 // 因此,可以把不变的属性和方法定义在prototype对象上,所有的实例都可以共享这些属性和方法
    23 
    24 // 给构造函数Dog的原型添加属性和方法
    25 Dog.prototype.favourite = '骨头'
    26 Dog.prototype.barking = function (){
    27   console.info('汪汪汪...')
    28 }
    29 // 实例中可以直接使用
    30 console.info(xiaohua.favourite) // 骨头
    31 // 而且原型中的方法是共享的
    32 console.info(xiaohua.barking === xiaohei.barking) // true
    33 
    34 // 5.构造函数的原型对象和实例的关系
    35 // 每个实例对象都有一个__proto__属性(原型),指向构造函数的原型对象prototype,所以实例对象可以使用构造函数原型中的方法
    36 console.info(xiaohua.__proto__ === Dog.prototype) // true
    37 
    38 // 实例对象可以使用方法:1.自身拥有的方法,2.顺着__proto__找到的构造函数prototype的方法
    39 
    40 
    41 // 6.原型对象prototype和构造函数的关系
    42 // 原型对象prototype有constructor属性,该属性为构造函数本身
    43 console.info(Dog.prototype.constructor === Dog) // true
    44 // 有因为实例对象的__proto__等于构造函数的prototype,所以每个实例的__proto__.constructor即是构造函数
    45 console.info(xiaohua.__proto__.constructor === Dog) // true
    46 console.info(xiaohei.__proto__.constructor === Dog) // true
    47 
    48 // 通过实例的__proto__.constructor属性可以明确是由哪个构造函数创建出来的
    49 
    50 //7.特殊情况需要手动把constructor属性指回来
    51 // 如重新给prototype赋值,会造成constructor丢失
    52 Dog.prototype = {
    53   barking: function (){
    54     console.info('汪汪汪...')
    55   }
    56 }
    57 // 因为重新给Dog.prototype赋值了一个对象
    58 console.info(Dog.prototype.constructor === Dog) // false
    59 
    60 // 手动把constructor属性指回来
    61 Dog.prototype = {
    62   constructor: Dog,
    63   barking: function (){
    64     console.info('汪汪汪...')
    65   }
    66 }
    67 console.info(Dog.prototype.constructor === Dog) // true
    68 
    69 // 8.原型对象(prototype)的原型(__proto__)
    70 // 原型对象也是对象,因此也因该有原型,即Dog.prototype.__proto__
    71 // 而这个原型对象的原型(Dog.prototype.__proto__)是Object构造函数的原型对象
    72 console.info(Dog.prototype.__proto__ === Object.prototype) // true
    73 // 也即是这个原型对象的原型的constructor属性(Dog.prototype.__proto__.constructor)为Object
    74 console.info(Dog.prototype.__proto__.constructor === Object) // true
    75 //这个原型对象的原型 的原型是null
    76 console.info(Dog.prototype.__proto__.__proto__)  // null
    77 
    78 // 以上即是原型链

    最后附上pink老师画的原型链示意图:

     

  • 相关阅读:
    JavaFX学习曲线日记2:声明用户接口
    深入学习JavaFX脚本语言
    JavaFX学习曲线日记2:声明用户接口
    JavaFX学习曲线日记1:探索JavaFX脚本
    深入学习JavaFX脚本语言
    略谈数学中的映射在其它领域的踪迹
    Using Swing's Pluggable Look and Feel
    JavaFX学习曲线日记1:探索JavaFX脚本
    赖勇浩:应对多核编程革命
    Using Swing's Pluggable Look and Feel
  • 原文地址:https://www.cnblogs.com/jyughynj/p/12547263.html
Copyright © 2011-2022 走看看