最近忙着面试,看了很多文章,抽出空重新理解了一下原型链,写了一种方便入门理解的方式,如果哪里错了,请大神勿喷,帮我指正。
1.foo.demo -> foo.proto ->Foo.prototype ->Foo.prototype.proto ->Object.prototype->Object.prototype.proto->NULL
2.Foo.demo->Foo.proto->Function.prototype->Function.prototype.proto ->Object.prototype->Object.prototype.proto->NULL
3.Function.demo->Function.proto->Function.prototype->Function.prototype.proto ->Object.prototype->Object.prototype.proto->NULL
//第一段代码
function Foo() {
this.demo=function () {
console.log('实例化对象foo的demo');
}
}
Foo.demo = function(){
console.log('Foo的demo');
};
Foo.prototype.demo = function() {
console.log('Foo原型的demo');
};
Function.demo = function(){
console.log('Function的demo');
};
Function.prototype.demo = function(){
console.log('Function原型的demo');
};
Object.prototype.demo = function(){
console.log('Object原型的demo');
};
var foo = new Foo();
foo.demo();//输出:实例化对象foo的demo,原因:this指向实例化对象foo
Foo.demo();//输出:Foo的demo,原因:找到了Foo.demo()
Function.demo();//输出:Function的demo,原因:找到了Function.demo()
//第二段代码
function Foo() {
// this.demo=function () {
// console.log('实例化对象foo的demo');
// }
}
// Foo.demo = function(){
// console.log('Foo的demo');
// };
Foo.prototype.demo = function() {
console.log('Foo原型的demo');
};
//Function.demo = function(){
// console.log('Function的demo');
//};
Function.prototype.demo = function(){
console.log('Function原型的demo');
};
Object.prototype.demo = function(){
console.log('Object原型的demo');
};
var foo = new Foo();
foo.demo();//输出:Foo原型的demo,原因: this.demo被注释掉,原型链向下寻找,
//foo.demo -> foo._proto_ ->Foo.prototype
Foo.demo();//输出:Function原型的demo,原因:Foo.demo()被注释掉,原型链向下寻找,
//Foo.demo->Foo._proto_->Function.prototype
Function.demo();//输出:Function原型的demo,原因:Function.demo()被注释掉,原型链向下寻找,
//Function.demo->Function._proto_->Function.prototype
//第三段代码
function Foo() {
// this.demo=function () {
// console.log('实例化对象foo的demo');
// }
}
// Foo.demo = function(){
// console.log('Foo的demo');
// };
// Foo.prototype.demo = function() {
// console.log('Foo原型的demo');
// };
//Function.demo = function(){
// console.log('Function的demo');
//};
// Function.prototype.demo = function(){
// console.log('Function原型的demo');
// };
Object.prototype.demo = function(){
console.log('Object原型的demo');
};
var foo = new Foo();
foo.demo();//输出:Object原型的demo,原因:
//foo.demo -> foo._proto_ ->Foo.prototype->Foo.prototype._proto_ ->Object.prototype
Foo.demo();//输出:Object原型的demo,原因:
//Foo.demo->Foo._proto_->Function.prototype->Function.prototype._proto_ ->Object.prototype
Function.demo();//输出:Object原型的demo,原因:
//Function.demo->Function._proto_->Function.prototype->Function.prototype._proto_ ->Object.prototype
后面如果再把Object.prototype.demo()注释掉的话,会报错,因为已经达到了原型链的终点。
原型链的继承
//创建Name构造函数
function Name() {
this.name = function () {
console.log("name")
}
}
//创建Firstname实例
function Firstname() {
this.firstname = function () {
console.log("firstname")
}
}
//将Name的原型对象指向Firstname
Name.prototype = new Firstname();
//通过Name实例化一个对象he
var he = new Name();
he.name(); //"name"
he.firstname(); //"firstname"
试题1:
var A=function(){}
A.prototype.n=1
var b=new A()
A.prototype={n:2,m:3}
var c=new A()
console.log(b.n,b.m,c.n,c.m)//1,undefined,2,3
试题2:
var A=function(){}
A.prototype.n=1
var b=new A()
A.prototype.n=2
A.prototype.m=3
var c=new A()
console.log(b.n,b.m,c.n,c.m)//2,3,2,3
值得注意的点:A.prototype.m的形式放后面b能读取到,A.prototype={n:2,m:3}这种形式放后面不能读取到,具体原因不清楚,还是少用集合的方式好,知道原因的大佬麻烦指出,谢谢!
试题3:
function Parent() {
this.a = 1;
this.b = [1, 2, this.a];
this.c = {demo: 5};
this.show = function () {
console.log(this.a, this.b, this.c.demo);
}
}
function Child() {
this.change = function () {
this.b.push(this.a);
this.a = this.b.length;
this.c.demo = this.a++;
}
}
Child.prototype = new Parent();
var parent = new Parent();
var child1 = new Child();
var child2 = new Child();
child1.a = 11;
child2.a = 12;
parent.show();//1 [1, 2, 1] 5
child1.show();//11 [1, 2, 1] 5
child2.show();//12 [1, 2, 1] 5
child1.change();//5 [1, 2, 1, 11] 4
child2.change();//6 [1,2,1,11,12] 5
parent.show();//1 [1, 2, 1] 5
child1.show();//5 [1, 2, 1, 11, 12] 5
child2.show();//6 [1, 2, 1, 11, 12] 5
值得注意的点:最后结果一个this.a=5,一个this.a=6,因为这个this指向的是child1和child2,而不是Child.prototype,this.a = this.b.length会使child1和child2各自创建自己的a