Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
原型链
JavaScript访问属性的机制
我们回顾一下上节的知识点:每个实例对象都有一个另一个实例对象作为原型,一环套一环。
继续摆出上节的例子:
function A(){
this.member1='abc';
}
var a = new A();
var b = Object.create(a);
写一个原型链:
b:{
b自己的成员
...
__proto__:a{
a自己的成员
...
__proto__:A.prototype{
constructor : A
A.prototype自己的成员
...
__proto__:Object.prototype{
constructor : Object
和一些其他的奇奇怪怪的东西
...
__proto__:null
}
}
}
}
在这个原型链下,原型链上游的成员是可以让原型链下游的对象直接调用的。例如:
当你访问b的一个属性,就先查找b有没有这个属性;有的话返回值,没有的话去b的原型找,即在a中找;以此类推,直到把所有的__proto__都找完了还没有,那就返回undefined。
现在通过重写上面的代码段来创建一些成员:
function A(){
this.member1="In A's code";
this.__proto__.constructor.prototype.member2="In A's prototype";
};
var a=new A();
var b=Object.create(a);
a.member3="Created by a itself";
b.member4="Created by b itself";
在往下看之前,可以自己思考一下,对于创建的成员member1、member2、member3、member4,对象a、b可以访问哪些成员,访问时他们属于哪个原型。
答案揭晓:
此时
b同时含有member1、member2、member3和member4,其中member4是自己创建的,member3是b的原型a创建的,member2是b的原型的原型A.prototype创建的,member1是a创建的。
可能有些人会感到疑惑:A是一个对象,那member1是不是属于A的呢?使用控制台打印得到:
A.member1:
undefined
看来this.member1="In A's code"并不会为A对象创建成员。那为什么a中会存在member1呢?这就涉及到new运算符的机制了:
我自己对于
new的理解:
- 先构建了一个空实例对象;
- 然后将对象的引用赋值给后面函数的
this,使得函数可以使用this指针创建成员;- 以后面函数的
prototype属性作为实例的原型,使得可以继承其方法。
这就是JS构建实例的基本原理!在下节我将给大家探讨修改成员时发生的事,大家不要错过~