重学前端:原型和原型链梳理

348 阅读3分钟

重学前端:原型和原型链梳理

基础知识重新学习,若有不对欢迎指正,感恩。

什么是构造函数?

在js里,使用__new__关键词调用的函数就是构造函数。

let p1 = new Person('zs',6,'男','basketball')

为什么要用构造函数?

达到封装目地,抽象出函数功能。

//没有封装
var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
//通过构造函数模式封装
function Person(name,age,gender,hobby){
  this.name = name
  this.age = age
  this.gender = gender
  this.hobby = hobby
  this.getName = function(){
    return this.name
  }
}
let p1 = new Person('zs',6,'男','basketball')
p1.getName(); // zs
let p2 = new Person('ls',6,'女','dancing')

什么是原型对象(prototype)?

函数(包括构造函数)天生自带一个prototype属性,他是一个指针,指向的是一个对象。

let p1 = new Array()
p1.prototype //返回的是一个对象

为什么需要原型对象(pototype)?

因为js没有直接通过面向对象继承父类的语法,所以设计了原型这个模式来实现对象的继承。

function Person(name,age,gender,hobby){
  this.name = name
  this.age = age
  this.gender = gender
  this.hobby = hobby
  this.getName = function(){
    return this.name
  }
}
let p1 = new Person('zs',6,'男','basketball')
p1.getName = function(){return this.age}
p1.getName() //6
let p2 = new Person('ls',6,'女','dancing')
p2.getName() //ls

上述代码每个Person实例对象都有一份__getName__方法的拷贝,在程序抽象上是不划算的,所以引入的prototype【原型对象】,把原型对象当作一个公共的区域,所有同一个类的实例对象都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。方便后期,以提升效率。

function Person(name,age,gender,hobby){
  this.name = name
  this.age = age
  this.gender = gender
  this.hobby = hobby
}
Person.prototype.getName = function(){
    return this.name
  }
let p1 = new Person('zs',6,'男','basketball')
p1.getName() //zs
let p2 = new Person('ls',6,'女','dancing')
p2.getName() //ls
//修改person的getName方法
Person.prototype.getName = function(){
    return this.name+this.age
  }
p1.getName() //zs6

什么是原型链?

对于一个构造函数A,继承自一个构造函数B,现在A的实例a对象想调用B构造函数定义的方法怎么办呢?

所以js内置对于所有对象内置了一个属性 __ proto __ ,这个属性的指针指向__构造函数的prototype__,而构造函数也是对象,也有__ proto __ 属性指向构造函数的构造函数(一般是顶层是Object),所以规定顶层的Object的prototype是null,所以当一个实例对象要使用某一个方法时,如果本身找不到,会从自身的构造函数的prototype对象里面找,一层层的,直到找到Object.prototype对象里面,如果还没有就是null。上述过程就是原型链。

原型图

令人疑惑(需要注意)的原型链

  • Function.__ proto __ === Function.prototype //因为Function这个函数是由自身构造的。
  • Function.prototype.__ proto __ === Object.prototype // Function.prototype这个对象是有Object这个函数对象构造出来的
  • Object.__ proto __ === Function.prototype //因为在js中 内置的函数对象Object(函数是一等公民)所以是函数构造的

原型链的总结

对于一个构造函数function Foo()

原型链是

Foo>Function.prototype>Object.prototype>null

对于这个构造函数的实例foo

原型链是

foo>Foo.prototype>Object.prototype>null