Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
原型链上的同名成员?
上节内容我们得知了原型链的存在,即JS访问成员时会沿着原型链一路访问到底。
这时自然而然就会衍生出一个问题:当这条原型链中存在两个相同名字的成员时,会发生什么?
function A(){
this.member1="In A's code";
this.__proto__.constructor.prototype.member1="In A's prototype";
};
var a=new A();
var b=Object.create(a);
a.member2="Created by a itself";
b.member3="Created by b itself";
注意!这次我在函数中创建了两个
member1变量,一个创建在a自身,一个创建在a的原型中。 此时在控制台输入a.member1,会得到:
"In A's code"
结果不出所料,a会访问顺着原型链最先找到的"member1"。
也就是说:当访问成员时,即使一条原型链上有多个名称相同的变量,在实例访问一个成员的时候也会访问到最先看到的那个成员。
我们来探讨一下另一个问题。
为成员赋值时发生了什么?
在我们访问b.member2时,我们访问的实际上是a的成员。那么,
在控制台中执行b.member2="Created by b itself";,
这时会发生什么?
分别在控制台中输入a.member2和b.member2,控制台显示:
"Created by a itself"
"Created by b itself"
那条赋值语句并没有修改a的成员的值,而是直接在b下创建了一个新的同名成员!
那么,根据上面的实践,我们可以总结出两条给成员赋值的规则:
- 为一个对象的成员赋值时,不同于访问,
Javascript只会查找这个对象本身含不含有该成员,含有则更改,不含有则创建。 - 由于实例和实例的原型是引用关系,因此在确立原型关系后修改一个原型链上游的对象就意味着下游的对象也变得“不一样”了。
牢记一点:
实例的原型是对另一个实例的引用!
实例的原型是对另一个实例的引用!
实例的原型是对另一个实例的引用!
有了这些知识,我相信大家就可以在原型链上为所欲为了。