😭原来原型原型链可以这样理解的
前言
在面试中常常被问到原型和原型链的概念,而且了解原型和原型链对我们使用javascript会有更深的理解
首先我们要了解什么是原型和原型链:
根据上面的代码和图片分析,按理来说,
Fo
是 Foo
构造函数生成的实例,而 Foo
的 prototype
并没有 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
关键字来创建的
- 创建一个新对象 {}
- 将实例对象的
_proto_
隐式原型指向了构造函数的原型对象- 让构造函数中的
this
指向我们的实例对象- 判断构造函数中有没有返回值,如果显示的是
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() //这个是实例方法
总结
原型原型链最终的目的是让所有的实例都能够共享其属性和方法
- 当一个对象查找属性和方法时会从自身查找,如果找不到就会通过
_proto_
指向被实例化的构造函数的原型(prototype
) - 隐式原型(
_proto_
)也是一个对象,指向构造函数的原型 - 除了最顶层的
Object
对象没有_proto_
,其他的所有对象都有_proto_
- 隐式原型
_proto_
的作用是让对象通过它来一直往上找属性和方法,直至找到最顶层的Object
的_proto_
,它的值是null
当我们想要从实例对象使用某一个属性或者方法时,例如:创建一个实例Fo
,然后 Fo
要使用 tostring
方法,首先 Fo
实例先从自身出发查找有没有该属性,发现并没有 tostring
方法。找不到,就往上查找,找到Foo
构造函数的 prototype
属性,还是没找到,但是构造函数 prototype
也是一个对象,对象的构造函数是 Object
, 所以就找到了 Object.prototype
下的 toString
方法。
转载自:https://juejin.cn/post/7220250935665754173