prototype原理

一、对于prototype的初步认识

对于JS而言一切皆为对象,那么创建对象是通过原型链的方式进行创建的(原型模式)。由于最近在细挖js的基础知识,让本人更能够深层次地去理解js地底层原理,为了提升自身的技术能力,需要接触理解原型链的原理。

1.1 什么是原型?什么是原型链?

在js中大部分的构造函数以及对象都是有prototype的属性,这是就是原型对象。再此之上,构建构造函数new实例化之后的对象与原型之间的关联线,叫原型链。

1.2 为什么需要使用原型链?

这样可以实现继承效果,每次构造函数的new实例化都会指向原型对象中,这样它们都有公共的属性以及方法,这样可以减少代码的占用空间。
只要属性以及方法都存在与原型链上都可以访问到。当我们需要使用原型链的一个变量时,它会先查找当前一层,未找到的话跳到上一层,直至找到为主。(要是未找到的话,直接报错)

1.3 原型链三角关系图

.prototype
.constructor
.__proto__
new
.__proto__
构造函数A
原型对象B
实例C
原型对象D即Object原型对象

1.3.1 .__ proto __ 与 .prototype的区别

观察到上图会发现两种访问原型对象的途径,现在来看看两者之间的区别:

  • .__ proto __ 是实例后对象所指向的原型对象,为隐式原型。
  • .prototype 是构造函数所指向的原型对象,为显式原型(只有构造函数才拥有)。

1.3.2 使用浏览调试器观看原型链的层与层之间的关系

我们先定义一个构造函数A,实例化后为实例C,并打印看出C的原型对象,并观察它一层层的原型对象。

<script>
export default {
    
    
  data(){
    
    
    return{
    
    

    }
  },
  mounted(){
    
    
    this.seePrototype()
  },
  methods:{
    
    

    seePrototype(){
    
    
      function A(){
    
    }
      let C = new A()
      console.log('c',C)
    }

  }
}
</script>

控制台显示
在这里插入图片描述
可以看出原型链的层层相关,并最终找到Object的原型对象,而它的指向的隐式原型为null。

1.4 原型链在平时编写js可以怎么使用?(结合本人目前碰到)

  1. 判断该对象是什么类型(变量的隐式原型 与 构造函数的显示原型比较,既是instanceof)
    变量.__ proto __ === Array等构造函数.prototype (简写 变量 instanceof Array等构造函数)
  2. 打印出该对象的类型
    Object.prototype.toString.call(变量)

1.5 原型对象的引用值是有共享(继承性的特征),那么修改它子类原型对象的引用值,会发生什么情况?

相关代码:

<script>
export default {
    
    
  data(){
    
    
    return{
    
    

    }
  },
  mounted(){
    
    
    this.checkPrototype()
  },
  methods:{
    
    
    checkPrototype(){
    
    
      //第一层 构造函数SuperType定义
      function SuperType(){
    
    
        this.num = ["1", "2", "3"];
      }

      //第二层 构造函数outSide定义
      function outSide(){
    
    }

      outSide.prototype = new SuperType()

      //实例化第二层函数outSide(instance1)
      let instance1 = new outSide();
      console.log('instance1',instance1)
      // 修改第一层的原型对象的引用值
      instance1.num.push('4')
      console.log(instance1.num)

      //实例化第二层函数outSide(instance2)
      let instance2 = new outSide();
      console.log('instance2',instance2)
      console.log(instance2.num)

    },

  }
}
</script>

运行截图:
在这里插入图片描述
由上述情况可以看出,我们在子类outSide原型对象中的父类SuperType原型对象,若对子类SuperType进行传参,会影响该原型链下的所有实例。(不管父类outSide原型对象在哪里多次实例化)
具体原型链更深层次的探讨之后会抽空认真再学习,这样才能研究透彻。

猜你喜欢

转载自blog.csdn.net/Ak47a7/article/details/129827177