Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一道关于this和原型链的JS题目 #16

Open
rico-c opened this issue Dec 16, 2018 · 0 comments
Open

一道关于this和原型链的JS题目 #16

rico-c opened this issue Dec 16, 2018 · 0 comments
Labels

Comments

@rico-c
Copy link
Owner

rico-c commented Dec 16, 2018

题目如下:

function Parent() {
    this.a = 1;
    this.b = [1, 2, this.a];
    this.c = { demo: 8 };
    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();//Q1
child1.show();//Q2
child2.show();//Q3

child1.change();
child2.change();

parent.show();//Q4
child1.show();//Q5
child2.show();//Q6

知识点

  • 原型链的查找规则
    • 当实例上存在属性时, 用实例上的
    • 如果实例不存在,顺在原型链,往上查找,如果存在,就使用原型链的
    • 如果原型链都不存在,就用Object原型对象上的
    • 如果Object原型对象都不存在, 就是undefined
  • 数组和字面量对象都是引用
  • this指向在引用时确认而不是定义时

解题思路

下面分别模拟Q1-Q6的执行情况

Q1:

直接调用 parent.show(),此时this指向parent,语句中的三条语句相当于分别在给window对象上赋值:

parent.a = 1;
parent.b = [1, 2, parent.a];
parent.c = { demo: 8 };

此时,parent对象应为:

{
    a:1,
    b:[1,2,1],
    c:{
        demo:8
    }
}
Q2:

在执行var child1 = new Child();语句时,child对象的a值为2,而因为后被手动赋值为11,所以child实例上的a被改为11,这时调用原型链上的show()方法,依次打印,

这里this.a根据原型链的查找规则,在实例上有a的赋值,所以直接使用实例上的值也就是11,其他值实例上没有,需要在原型上寻找,所以输出b为[1,2,this.a],

而这里的this.b因为是数组,为引用类型,在执行var parent = new Parent();时被定义在parent实例上,所有this.a的指针指向共同的引用地址,所以为1 ,

this.c因为也是引用类型,指针也被指向共同的引用对象地址。

Q3:

实例上的a被重新赋值,所以this.a 的输出被改为12,其余执行步骤同Q2。

Q4:

相当于再次调用parent实例上的show方法,因为数据没有发生变动,所以输出值同Q1。

Q5:

因为在调用this.change时,this.a的值被赋值为this.b数组的长度,所有这里的a输出为4,this.b的值使用引用地址b数组,因为在下一步中又执行了一次对this.b数组的push,所以这里打印this.b是被push两次后的数组,而this.c也是被push两次后的数组的长度,注意因为this.a和this.c的数据类型不同,所以this.a是单独的内存,而this.c则是使用相同一块内存。

Q6:

又对this.b数组执行了一次push,所以这次this.a的输出应为数组的当前长度也就是5,this.c的值也是数组长度也就是5。

答案

在chrome控制台中运行代码得到结果如下:

jietu20181216-183105

@rico-c rico-c added the 笔记 label Dec 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant