原型与原型链的理解

1.为什么有原型的存在

例如人Person这个构造函数,它有一些公共方法和属性,不想每次创建一个实例重复添加属性,这时让构造函数的原型来存储这些公共方法和属性,节约内存

2.帮助理解的图(必看)

在这里插入图片描述

3.基本概念

乍一看图好复杂,先不急,先记住以下概念:

1._proto_和prototype: js对象分为函数对象和普通对象,js对象都有_proto_这个属性,确切说是对象的[[prototype]]属性,只是在一些主流浏览器中会用_proto_来表示[[prototype]],那么顺带提一下,在ES5中用Object.getPrototypeOf函数获得一个对象的[[prototype]],ES6中,使用Object.setPrototypeOf可以直接修改一个对象的[[prototype]];但只有函数对象有prototype这个属性
2. js中常见的内置对象:Function、Object、String、Array 、Boolean 、Number 等
3. 在js 里万物皆对象,函数(或叫作方法)Function是对象,函数的原型是对象,即Function.prototype,原型对象prototype有一个默认的constructor属性,用于记录实例是由哪个构造函数创建
4. 函数对象会继承函数原型对象的属性、方法
5. Function是最顶层的构造器,Object是最顶层的对象;从原型链讲Function继承了Object,从构造器讲Function构造了Object
6. 以Person对象为例:

准则1. Person.prototype.constructor == Person // **准则1:原型对象(即Person.prototype)的constructor指向构造函数本身**
准则2. person01.__proto__ == Person.prototype // **准则2:实例(即person01)的__proto__指向其构造函数的原型对象即Person的原型对象,即Person.prototype,来保证实例能够访问原型对象中的属性、方法**

4.上代码来理解图

//上方:
function Foo()
let f1=new Foo()
let f2=new Foo()
Foo.prototype.constructor = Foo// 准则1
f1.__proto__ = Foo.prototype; // 准则2
f2.__proto__ = Foo.prototype; // 准则2
Foo._proto_=Function.prototype// 准则2,Foo的构造函数是Function
Foo.prototype.__proto__ = Object.prototype; // 准则2 (Foo.prototype本质也是普通对象,Object是最顶层的对象,可以理解为Object创建了Foo.prototype这一实例,适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止


//中间
function Object()
let o1 = new  Object();
let o2 = new  Object();
o1.__proto__ = Object.prototype; // 准则2
o2.__proto__ = Object.prototype; // 准则2
Object.prototype.__proto__ = null; // 原型链到此停止
Object.prototype.constructor = Object; // 准则1
Object.__proto__ = Function.prototype // 准则2 (Object本质也是函数Function)
Function.prototype.__proto__ =  Object.prototype; // 准则2 (Function.prototype本质也是普通对象,适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止

//下方
function Function()
Function.prototype.constructor = Function; // 准则1
Function.__proto__ = Function.prototype // 准则2,名为Function的函数它其实也是Function对象的实例


结论

由此可以得出结论:
除了Object的原型对象(Object.prototype)的__proto__指向null,其他内置函数对象的原型对象(例如:Array.prototype)和自定义构造函数的__proto__都指向Object.prototype, 因为原型对象本身是普通对象。
即:

Object.prototype.__proto__ = null;
Array.prototype.__proto__ = Object.prototype;
Foo.prototype.__proto__  = Object.prototype;

注意

比如有一个原型对象属性Person.prototype.color="red"
那么实例person1、person2都继承了,如果某一实例修改了这一属性并不会影响到原型对象的属性从而影响到其他实例继承这一属性,只有改变原型对象的属性才能做到

转载于https://juejin.cn/post/6844903989088092174

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值