浅谈原型和原型链以及其应用案例

2,419 阅读3分钟

什么是原型

  1. 所有引用类型都有一个__proto__ (隐式原型)属性,属性值是一个普通对象
  2. 所有函数都有一个prototype(显式原型)属性,属性值是一个普通对象
  3. 所有引用类型的__proto__都指向他的构造函数的prototype

example

function Father(name) {
        this.name = name
    }
    let Son = new Father('小头爸爸')
    console.log(Son.__proto__ === FAther.prototype) // true
    console.dir('Son': Son) 
    console.dir('Father': Father)

echo

Son: Father {
name: '小头爸爸',
__proto__ : Object
}

Father: Father () {
name: '小头爸爸',
prototype:{...}
__proto__: ƒ (...)
}

什么是原型链

当访问某个对象的属性时,会现在这个对象本身属性上查找,如果没有找到,就去他的__proto__ 查找,既他的构造函数的prototype查找,如果没有找到,就去他的构造函数的prototype.__proto 查找。这样一层一层的查找就会形成一个链式的结构,这就是原型链

  1. 一直往上层查找,直到找到null还没有找到,则返回undefined
  2. Object.prototype.proto = null
  3. 所有从原型或更高级原型中的得到、执行的方法,其中的this在执行时,指向当前这个触发事件执行的对象

原型的作用

共享方法

实战

按照如下要求实现Person 和 Student 对象

  1. Student 继承Person
  2. Person 包含一个实例变量 name, 包含一个方法 printName
  3. Student 包含一个实例变量 score, 包含一个实例方法printScore
  4. 所有Person和Student对象之间共享一个方法
    function Person(name) {
       this.name = name
       this.printNama = function () {
           console.log('Person printNama ');
       }
   }
   Person.prototype.commen = function () {
       console.log('commenMethods')
   }
   function Student(name, score) {
       Person.call(this, name)
       this.score = score
       this.printScore = function () {
           console.log('Student printScore');
       }
   }
   Student.prototype = new Person()
   let person = new Person('小红', 30)
   let student = new Student('小敏', 20)
   console.log(Student.commen === Person.commen)
   console.log('student', student)
   console.log('person', person)

完整回答原型,原型链

  • 首先原型的作用是用来共享方法的,比如我们用的平时用的数组,对象,这些API,还有判断数据类型Object.prototype.toString.call()方法, instanceof方法,在vue中使用插件,将其挂载到vue的原型上,都是利用原型来实现的。当我们使用构造函数,来新建对象的时候。每个构造函数都有一个prototype,他是一个对象,里面就包含了构造函数所有的共享方法。当我们使用构造函数新建的这个对象的时候,这个对象里面包含了一个指针__proto__,这个指针指向了构造函数的prototype属性, 当我我们访问这个对象的某个属性时,如果他身上不存在,就回去他的原型对象上去找,原型对象又有自己的原型,这样一层一层嵌套,形成的链式结构,叫原型链

行文总结

  1. 文章用到了new ,那么new的原理和实现过程是必须掌握得,new里面是不是也用到原型,原型链呢
  2. 文章用了call来改变this指向,那他的兄弟们apply,bind你又了解多少?,能不能手写一个 ?
  3. 最后一个实现了继承,那你知道还有其他的继承方式吗?
  4. 了解es6吗? 能不能用es6的类,来实现一个继承呢?
  5. 原型的应用还有哪些呢,比如? 数组的方法foreach, map,filter,some.every.... 为什么数组可以用呢,是否可以手写数组的某些方法?
  6. instanceof的检测原理是什么呢?

后面我们的探索~~~

1 new的原理和实现过程

  1. call,apply,bind相关 手写call,apply,bind 3, 4 继承的几种方式

5.手写数组API

6. instanceof