1.4 JS-原型

本系列文章是针对前端面试之道网站所做的个人注解

原文引用

前端面试之道-原型

image.png

原文对原型的描述并不清晰,下面将尽量清晰直观的让大家彻底理解原型。

原型

预知识

预知识背下来即可,可以当作数学里的公理。

  • 函数也是一种对象,只不过是一种特殊的对象。毕竟JS引用类型都叫Object。
  • Object.prototype 是由引擎创建的,除了这个对象,其他对象都是通过构造器 new 出来的。let a = { b: 1 } 这个字面量内部也是使用了 new Object()
  • Function.prototype是由引擎创建的,除了这个函数,其他函数都是new Function()出来的,function Foo() {}function 就是个语法糖,内部等同于 `new Function()。
  • 实例:let o1=new Object();o1是Object()的实例对象。
  • 构造函数:let o1=new Object();Object()是o1的构造函数。
  • Function.proto === Function.prototype

原型定义

原型是个对象,全称是原型对象。

xxx的原型对象里包含xxx的公有属性和方法。你可以理解为原型对象是一个容器,里面装着xxx对象需要用到的各种方法。比如打印Array.prototype会出现~

image.png
原型让你无需重复声明公有属性。省代码,省内存。

prototype属性

prototype 属性是一个显式原型属性,只有函数才拥有该属性。除了let fun = Function.prototype.bind()这样创建出来的函数,基本上所有函数都有这个属性。

xxx.prototype包含一个指针,这个指针指向的内存里存储了xxx的原型对象。

prototype 如何产生的

有些函数已经内置了prototype属性,比如上文提到的Array。

除了已经内置prototype属性的函数,当我们新声明一个函数时,prototype这个属性也会被自动创建。

function Foo() {} // 此时,Foo.prototype就被自动创建了,并且Foo.prototype指向的原型对象里也拥有一个自动创建的属性:constructor。
复制代码

image.png

constructor属性

constructor也包含指针,指向prototype对应的函数。在上面的例子中,指向的就是 Foo。

constructor 是一个公有且不可枚举的属性。一旦我们改变了函数的 prototype ,那么新对象就没有这个属性了(当然可以通过原型链取到 constructor)。

image.png

那么你肯定也有一个疑问,这个属性到底有什么用呢?其实这个属性可以说是一个历史遗留问题,在大部分情况下是没用的,在我的理解里,我认为他有两个作用:

1.让实例对象知道是什么函数构造了它

2.如果想给某些类库中的构造函数增加一些自定义的方法,就可以通过 xx.constructor.method 来扩展

_proto_属性

这是每个对象都有的隐式原型属性,指向了创建该对象的构造函数的原型。

_ proto _ 如何产生的

当我们使用 new 操作符时, 新对象被添加了 proto 并且链接到构造函数的原型上。

prototype和_proto_的区别

prototype和_proto_都存着原型的地址,只不过_proto_所有对象都有,prorotype只挂载在函数上。

原型链

实例可以通过_proto_来寻找上层属性。_proto_将各个对象连接起来组成了原型链。

总结

读完上面的内容之后,把总结背下来就可以轻松面对所有原型相关问题啦~

  1. 每个函数都有 prototype 属性,除了 Function.prototype.bind()创建的函数,该属性指向该函数的原型对象。
  2. 原型对象存储了函数的公有属性和方法。让你无需重复声明公有属性。省代码,省内存。
  3. 每个原型对象都有constructor属性,指向对应的函数。
  4. 每个对象(实例)都_proto_有属性,指向了创建该对象(实例)的构造函数的原型。
  5. _proto_将各个对象连接起来组成了原型链。
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享