|
导读网页的本质就是超级文本标记语言,通过结合使用其他的Web技术(如:脚本语言、公共网关接口、组件等),可以创造出功能强大的网页。因而,超级文本标记语言是万维网(Web)编程的基础,也就是说万维网是建立... 网页的本质就是超级文本标记语言,通过结合使用其他的Web技术(如:脚本语言、公共网关接口、组件等),可以创造出功能强大的网页。因而,超级文本标记语言是万维网(Web)编程的基础,也就是说万维网是建立在超文本基础之上的。超级文本标记语言之所以称为超文本标记语言,是因为文本中包含了所谓“超级链接”点。 本篇文章给大家带来的内容是关于javascript原型链的一道面试题的分析(详细),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。在基础面前,一切技巧都是浮云。 题目是这样的要求写出控制台的输出. 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();
child1.show();
child2.show();
child1.change();
child2.change();
parent.show();
child1.show();
child2.show();题目涉及的知识点
解题需要的知识点细节1.构造函数,都有一个prototype属性,指向构造函数的原型对象,实例会共享同一个原型对象; 2.实例生成时,会在内存中产生一块新的堆内存,对实例的一般操作将不影响其他实例,因为在堆内存里占据不同空间,互不影响; 3.每一个实例都有一个隐式原型__proto__指向构造函数的原型对象; 4.this的指向问题,常见的情况包含如下几种: 4.1 作为对象方法时,谁调用就指向谁(本题中主要涉及这一条) 4.2 作为函数调用时,指向全局顶层变量window 4.3 作为构造函数调用时,即new操作符生成实例时,构造函数中的this指向实例 4.4 call和apply方法中,显示指定this的绑定为指定上下文 5.字面量的方式(也有资料将literal翻译为直接量,个人认为后一种翻译其实更直观更形象)进行对象和数组赋值(数组本质也是对象)时,都是引用,即在堆内存生成资源,在栈内存生成变量,然后变量指向资源的地址。 6.原型链的查找规则遵循最短路径原则,即先查找实例属性,然后顺着原型链去查找指定的属性,直至原型链末端的Object.prototype和null,如果实例自身及整个原型链都不存在所查找的属性则返回undefined 7.赋值语句对于原始值赋值和引用类型赋值时的细节区别. 开始剖题1.parent.show()基本没什么可解释的。 2.child1.show()
此处令人迷惑的是this.b指向的数组最后一列为什么是 先来看一下child1的样子: 当执行child1.show()这个方法时,由于child1作为Child的实例,是拥有a这个属性的,所以show()方法中的this.a会直接指向这个属性的值,也就是11,而不会继续沿原型链取到__proto__所指的对象上的a属性; 接着寻找this.b,由于child1是没有b这个属性的,所以会沿原型链取到parent上的b属性,其值是一个数组,前2项是常量没什么好说的,数组的最后一项是一个引用,而此处的指针并不是一个动态指向,因为在new Parent()这一步的时候它已经被执行过一次,确定指向了parent.a所指向的资源,也就是child1.__proto__中的a属性所指向的资源,即数值1。 延伸思考需要注意的是:
2.那怎样让child1.__proto__.b数组的第三项也输出11呢? 实例化后修改 get/set方法同步 3.child2.show()如果理解了上面的解释,那么此处同理即可得出答案:12 [1,2,1] 5 接着代码执行了: child1.change(); child2.change(); 4.parent.show()parent是一个Parent类的实例,Child.prorotype指向的是Parent类的另一个实例,两者在堆内存中是两份资源,互不影响,所以上述操作不影响parent实例, 5.child1.show(),child2.show()child1执行了change()方法后,发生了怎样的变化呢? this.b.push(this.a) this.a = this.b.length this.c.demo = this.a++ 接着,child2执行了change()方法, 而child2和child1均是Child类的实例,所以他们的原型链指向同一个原型对象Child.prototype,也就是同一个parent实例,所以 this.b.push(this.a) 由于this的动态指向特性,this.b会指向Child.prototype上的b数组,this.a会指向child2的a属性,所以Child.prototype.b变成 [1,2,1,11,12]; this.a = this.b.length this.c.demo = this.a++ 接下来执行输出命令,最终结果将输出: 延伸思考 收获和反思1.基础知识本来就是零散的细节,必须本着死磕到底的心态进行学习。 2.基础知识是最枯燥的,也是真正拉开人和人之间差距的东西,也是你想进入大厂必须要跨过的门槛,重要却不紧急。同样是菜鸟,有的人3-5年后成为了前端架构师,有的人3-5年后还在用层出不穷的新框架给按钮绑事件,想成为怎样的人,就要付出怎样的努力,大多数时候都是没毛病的。基础很重要!很重要!很重要! 以上就是javascript原型链的一道面试题的分析(详细)的详细内容,更多请关注php中文网其它相关文章! 网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。 |
温馨提示:喜欢本站的话,请收藏一下本站!