腾讯面试题0804
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.a = 2; 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(); child2.change(); 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
记住
1 每个构造函数 都有一个原型[[prototype]]属性 指向构造函数的原型对象
2 每个实例生成的时候 都会在内存中产生一块新的堆内存
3 每实例都有一个隐式原型__proto__ 指向构造函数的原型对象
4 this的指向 取决于this调用时的位置, 在这道题中, 也可以简单理解为, 谁调用方法, this就指向哪个对象
5 数组和字面量对象 都是 引用
6 原型链的查找规则: 就近原则
当实例上存在属性时, 用实例上的
如果实例不存在,顺在原型链,往上查找,如果存在,就使用原型链的
如果原型链都不存在,就用Object原型对象上的
如果Object原型对象都不存在, 就是undefined
解题思路
首先 来看Parent的方法 一共有 a b c show 四个方法
Parent a=1 b=[1,2,1] c.demo=5
然后 Child的方法 a change两个方法 继承来自Parent的b c show
Child a=2 b=[1,2,1] c.demo=5
parent.show() 因为parent = new Parent() 所以输出 1 [1,2,1] 5
child1.show() 因为child1 = new Child()且child1.a = 11 所以输出 11 [1,2,1] 5
child2.show() 因为child2 = new Child()且child2.a = 12 所以输出 12 [1,2,1] 5
Child.change() 改变了b a c.demo的值 然而在Child中并没有b c.demo的存在 所以顺着原型链往上找 在Parent上找到了 b=[1,2,1] c.demo=5
Child上面的b = [1,2,1] c.demo = 5
change改变的Child上的b c.demo 且是永久性的改变
child1.change()
this.a = 11 this.b.push(this.a) //b=[1,2,1,11] this.a = this.b.length // a=4 this.c.demo = this.a++ // c.demo=4 a=5
child1的 a = 5
此时 Child上
b=[1,2,1,11] c.demo=4
child2.change()
this.a = 12 this.b.push(this.a) //b=[1,2,1,11,12] this.a = this.b.length // a=5 this.c.demo = this.a++ // c.demo=5 a=6
child2的a = 6
此时 Child上
b=[1,2,1,11,12] c.demo=5
child1.show() 要输出 a b c.demo,a是自身有的 b c.demo自身没有往上找
a = 5 b = [1,2,1,11,12] c.demo = 5
child2.show() 同上 a是自己的
a = 6 b = [1,2,1,11,12] c.demo = 5