java原型链_原型与原型链

今天看了github上面的某位大佬对原型与原型链的文章 讲解很透彻 文章下面贴地址

prototype

每个函数都有prototype属性,如下

FlhjUzcXSi9VgzTXxoiITVxR7lMj.png

这个函数的prototype到底是什么呢,是函数的原型吗?

其实,函数的prototype都会指向一个对象,这个对象 就是调用改构造函数而创建的实例的原型,也就是上图的a b的原型

什么是原型呢?

每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

用过一张图来表示构造函数与实例之间的关系

8a778a443eaf2a9891c6b19d87e2f08b.png

那么上面的变量 ab是怎么访问到score的prototype.name的呢?

这里就要提出第二个属性

___ proto ___

这是每个JavaScript对象都会有的属性 叫做_ proto _ 这和属性 指向该对象的原型 即是

function score () {}

score.prototype.name = "张三"

var b= new score()

b.__proto__.name //"张三"

这里可以看到 b._ proto_ 是指向score.prototype的 或者我们可以证明

score.prototype == b.__proto__ //true

现在我们知道

构造函数 prototype 指向原型 构造函数可以生成实例 实例的 _ proto _ 指向原型

于是关系图可以这么理解

6dac86b8a9028796d75f750133431ae0.png

这里构造函数 和 实例都指向 原型 那么会不会有 原型指向构造函数与实例呢?

constructor

没有指向实例的方法 因为 会有多个实例 但是有指向构造函数的方法 就是constructor 每个原型都有一个constructor属性指向关联的构造函数

FuZBPzjSstr5QotCzB-qLIZlkrJK.png

可以看出来constructor指向构造函数本身

总结一下 现在得出结论

FsyQCad9cdtMS9wJQ6FFKGpNNRw_.png3

console.log(score.prototype.constructor == score)

console.log(score.prototype == a.__proto__)

再更新一下图

e1791b52772ee32f986f079ae32749cc.png

实例与原型

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

function score () {}

score.prototype.age="20" //在原型链上面赋值 age = 20

var a = new score()

a.age

"20" //age指向原型链上面

a.age= "10"

"10" //这时候指向a实例上面

delete a.age;

a.age

"20" //age指向原型链

当实例没有age这个属性 他会在原型链上面找

当给实例赋值的时候 就会覆盖prototype上面的属性 但是 prototype上面的属性依旧存在

当将实例上面的age删除的时候 就会依旧打印出原型链上面的属性

这里思考一个问题 JavaScript万物皆对象 name prototype的对象是什么呢?

原型的原型

我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它

Object.prototype.name = "张三"

var obj = new Object();

console.log(obj.name) // 张三 //和上面同理 来自原型链上面的name

Object.prototype.constructor == Object

现在关系图再次更新

016704f4dacc53f262e16d9aaeb698cc.png

原型链

那 Object.prototype 的原型呢?

console.log(Object.prototype.__proto__)

null

null 表示“没有对象”,即该处不应该有值

所以 Object.prototype.proto 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。

最后整理关系图

213b640a8f6b71afc0f80cd6d02dc2a5.png

图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。

最让人不注意的就是日常引用要注意的问题

首先 看下面代码

function score () {}

var a = new score()

console.log(a.constructor == score)

答案是 true

当获取 a.constructor 时,其实 a中并没有 constructor 属性,当不能读取到constructor 属性时,会从 a的原型也就是 score.prototype 中读取,正好原型中有该属性,所以相当于:

person.constructor === Person.prototype.constructor

学过java的人可能会将JavaScript的原型链理解为继承 但是 JavaScript里面一直以来都没有这个说法

你不知道的JavaScript 里面有一句话

继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值