likes
comments
collection
share

😭原来原型原型链可以这样理解的

作者站长头像
站长
· 阅读数 20

前言

在面试中常常被问到原型和原型链的概念,而且了解原型和原型链对我们使用javascript会有更深的理解

首先我们要了解什么是原型和原型链:

😭原来原型原型链可以这样理解的

😭原来原型原型链可以这样理解的 根据上面的代码和图片分析,按理来说,FoFoo 构造函数生成的实例,而 Fooprototype 并没有 toString 方法,那么为什么 Fo 能获得 toString方法。

首先 Fo 实例先从自身出发查找有没有该属性,发现并没有 tostring 方法。找不到,就往上查找,找到Foo 构造函数的 prototype 属性,还是没找到,但是构造函数 prototype 也是一个对象,对象的构造函数是 Object , 所以就找到了 Object.prototype下的 toString 方法。

此外要补充几个概念

javascript 中所有的对象(除了null)都具有一个 _proto_属性(隐形原型),该属性指向该对象的原型(prototype) 原型对象 默认会有一个特殊属性 constructor ,这个属性又指向原型对象本身

function Foo(){}
var Fo = new Foo()
console.log(Fo._proto_ === Foo.Prototype)   //true
console.log(Foo._proto_ === Object.Prototype)   //true
console.log(Foo.Prototype.constructor  === Foo) //true

😭原来原型原型链可以这样理解的

构造函数是用来创建新的实例对象,使用 new 关键字来创建的

  1. 创建一个新对象 {}
  2. 将实例对象的 _proto_隐式原型指向了构造函数的原型对象
  3. 让构造函数中的 this 指向我们的实例对象
  4. 判断构造函数中有没有返回值,如果显示的是 return 了一个对象,则返回该对象,如果没有返回值或者返回的不是一个对象,那么返回一个新创建的对象,也就是会生成一个全新的对象
function People(){
    this.name = '张三'
    this.age = 18
   // return {address:'广东'}
   // return 20
}
var people  = new People()
console.log(people)
//注释的第一行打开会返回{address:'广东'},而第二行打开会返回{name:'张三',age:18}

此外我们为什么要有原型和原型链呢?

实际上原型原型链的最终目的是让所有的实例对象能够共享其属性和方法

function People(){}
var people1 = new People()
var people2 = new People()

people1.haveEvent = ()=>{
    console.log('这个是实例方法')
}
people1.haveEvent() //这个是实例方法
people2.haveEvent()  //TypeError: people2.haveEvent is not a function

从上面代码我们可以看的出 people1有这个方法,而 people2没有,如果想让people2也拥有这个方法要怎么办呢,重新写一遍这个方法?可以是可以,但是没必要,这样如果实例对象过多,添加一个方法就太麻烦和浪费资源

我们可以通过在原型上添加属性和方法,使用原型链来调用

function People(){}
var people1 = new People()
var people2 = new People()

People.Prototype.haveEvent = ()=>{
    console.log('这个是实例方法')
}
people1.haveEvent() //这个是实例方法
people2.haveEvent()  //这个是实例方法

总结

原型原型链最终的目的是让所有的实例都能够共享其属性和方法

  1. 当一个对象查找属性和方法时会从自身查找,如果找不到就会通过_proto_指向被实例化的构造函数的原型(prototype
  2. 隐式原型(_proto_)也是一个对象,指向构造函数的原型
  3. 除了最顶层的Object对象没有 _proto_ ,其他的所有对象都有_proto_
  4. 隐式原型_proto_ 的作用是让对象通过它来一直往上找属性和方法,直至找到最顶层的 Object_proto_,它的值是 null

当我们想要从实例对象使用某一个属性或者方法时,例如:创建一个实例Fo,然后 Fo要使用 tostring 方法,首先 Fo 实例先从自身出发查找有没有该属性,发现并没有 tostring 方法。找不到,就往上查找,找到Foo 构造函数的 prototype 属性,还是没找到,但是构造函数 prototype 也是一个对象,对象的构造函数是 Object , 所以就找到了 Object.prototype下的 toString 方法。

转载自:https://juejin.cn/post/7220250935665754173
评论
请登录