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
記住javascript
1 每一個構造函數 都有一個原型[[prototype]]屬性 指向構造函數的原型對象java
2 每一個實例生成的時候 都會在內存中產生一塊新的堆內存數組
3 每實例都有一個隱式原型__proto__ 指向構造函數的原型對象函數
4 this的指向 取決於this調用時的位置, 在這道題中, 也能夠簡單理解爲, 誰調用方法, this就指向哪一個對象this
5 數組和字面量對象 都是 引用spa
6 原型鏈的查找規則: 就近原則prototype
當實例上存在屬性時, 用實例上的
若是實例不存在,順在原型鏈,往上查找,若是存在,就使用原型鏈的
若是原型鏈都不存在,就用Object原型對象上的
若是Object原型對象都不存在, 就是undefinedcode
解題思路對象
首先 來看Parent的方法 一共有 a b c show 四個方法blog
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