每一个JavaScrip对象(除null以外)都与另一个对象相关联,“另一个”对象就是我们数之的原型,每一个对象都能从原型继承属性。假设要查询 a 对象的属性x,如果a中不存在x属性,那么将会继续在a的原型对象中查询属性x。如果原型对象中也没有x,但这个原型对象也有对象,那么继续在这个原型对象的原型上执行查询,直到找到x或者查找到原型为null的对象为止。可以看到,对象的原型属性就构成了一个“链”,通过这个“链”可以实现属性的继承,我们称之为原型链。
var a = {} // a从Object.prototype 继承对象的方法
a.x = 1 // 给a定义了一个属性x
var p = inherit(o) // p 继承o和objct.prototypep.y
p.y = 2 // 给p 定义了属性y
var q = inheri(p) // q 继承了p\o\object.prototype
q.z = 3 // 给q 定义了属性z
var s = q.toString(); // toString继承自object。prototype
q.x + q.y // 返回 3 x和y分别继承自 a 和 p
现在,假设给对象a的属性x 赋值,分为三种情况
- a中存在x属性 赋值操作之该案已有属性x的值
- a中不存在x属性 赋值操作给a添加x属性
- a继承自属性x 新创建的同名属性x 将覆盖原有的继承属性x
属性赋值操作首先检查原型链,以此判定是否允许赋值操作,如果a继承自一个只读属性x,那么赋值操作将不被允许。如果允许属性赋值操作,也只是在原始对象上创建或对已有的属性赋值,而不会修改原型链
var a = {r:1}
var c = inherit(a) //c继承属性r
c.x = 1;
c.y = 1;
c.r = 2; //c 覆盖继承来的属性r
a.r; // 返回1 原型对象的属性没有改变
综上,属性赋值只有三种结果,1 赋值失败 2 创建一个属性 3 在原始对象中设置属性,但有一个例外,a继承自x属性,而x属性是一个具有setter方法的accessor属性,这时候,将调用setter方法,setter方法是由对象a调用的,而不是定义这个属性的原型对象调用的,因此,如果setter方法定义任意属性,这个操作只是针对a本身,并不修改原型链
来源:CSDN
作者:Rui.T
链接:https://blog.csdn.net/weixin_45779569/article/details/104750004