基于内存版的JS原型链解析(超详细)

思维导图

在这里插入图片描述

前言

  • 网上扣的图,哈哈。不太了解原型链的同学乍一看可能有点蒙,不过,没关系,读完此篇文章,我们再回头来看~
  • 之前有转过原型链的文章,当时自己也是一知半解。所以自己又重新梳理了一遍!

函数的prototype属性

###先看代码
在这里插入图片描述

  • 每个函数都有一个prototype属性,它默认指向一个空的Object对象。
  • 原型对象中constructor,它指向函数对象。
  • 作用:函数的所有实例自动拥有原型中的属性(方法)。
  • 注:方法也是属性哦,只不过它可以执行。

显式原型

每一个函数都有一个prototype,即显式原型

隐式原型

每一个实例对象都有一个__proto__,可称为隐式原型

Console.log(Fn.prototype===fn.__proto__) //true
  • 对象的隐式原型的值等于其构造函数的显式原型的值
  • 上面加粗的这句话很核心哦,理解原型链的基本~
  • 理解:共同存储的对象的引用,指向同一块地址值

显式原型的生成

function Fn(){
}
//内部语句是这样的
this.prototype = {}
  • 注意:Fn.prototype === {} //false
  • 这里 {} 是为了代表Object空对象

隐式原型的生成

var fn = new Fn(); 
//内部语句是这样的:
this.__proto__ = Fn.prototype

Java程序员的理解

函数对象

  • 函数对象即class 类

实例对象

  • new class 类产生对象

Object

即Object对象

JavaScript原型链在内存中的展现形式

在这里插入图片描述

  • 既然讲到了内存,就离不开地址值啦。【要理解原型链,上图要求自己画出~】
  • 上图栈中存在三个地址引用,分别是:Object函数对象,fn实例对象,Fn函数对象【实例对象和函数对象要区分哦】
  • 我们发现:fn的__propto__和Fn的prototype指向的是同一块地址值,所以二者相等。
  • Object函数对象prototype和Object空对象的__proto__指向的是同一块地址值。
  • Object原型对象的__proto__指向null【原型链的尽头】
  • 总结:所谓的原型链的全称为隐式原型链,即__proto__所指向的地址链。
  • JavaScript也是遵循“一生二,二生三,三成万物的思想~“

思维导图上的规律

在这里插入图片描述

  • 函数的显示原型对象指向的是空的Object实例对象(但是Object不满足),这一点可以看地址分析的那张图,Object函数指向的是Object原型对象。
console.log(Fn.prototype instanceof Object) //true
console.log(Object.prototype instance Object) //false
console.log(Function.prototype instance Object) //true
  • 所有函数都是Function的实例,包括Function。
    在这里插入图片描述
    这里就比较有意思了,想要理解这句话首先要明白Function是js的内置对象,所有函数都是通过new Function() 的来的,包括Function自己。所以就有了下面这句话:
  • 所有函数的__proto__都是一样的,这里也包括Object函数哦,这句话可以在上图找到答案。
console.log(Function.prototype === Function.prototype)  //true
  • Object的原型对象是原型链的尽头
console.log(Object.prototype.__prototype__) //null

属性问题

  • 讲了这么多,原型链到底有啥用?
  • 下面来看看原型链的作用【属性的存储】

get【属性查找】

*访问对象的属性时
*先在自身属性中查找,找到后返回如果没有找到,就按照__proto__构成的地址链查找,直到null,如果最终没有找到,返回undefined,(如果是方法,则报错:xxx is not a function)
*别名:隐式原型链
*作用:查找对象的属性(方法)

set【设置属性】

  • 设置属性时,不会查找原型链,如果当前对象中没有此属性,则直接添加此属性并设置其值,如果有则改变其值。

验证

function Fn(){
}
Fn.prototype.a = 'xxx';
var fn1 = new Fn();
console.log(fn1.a,fn1) //xxx,fn1对象
var fn2 = new Fn();
fn2.a ='yyy';
console.log(fn1,fn2);

结尾

  • 至此,是否对原型链有了新的理解呢?
  • 如果有错的地方,还请指正,共勉~
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值