原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。(二)

简介: 原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。

原型链


原型链: 通过对象__proto__属性指向函数的原型对象(函数.prototype)一层一层往上找,直到找到Object的原型对象(Object.prototype)为止,层层继承的链接结构叫做原型链(通过proto属性形成原型的链式结构,专业术语叫做原型链)


上述概念其实不够严谨,其实原型链的尽头是null,下面是我自己画的一个原型链


9841c1e65ea143c0ba309b32dae1672e.png


乍一看这也太复杂了吧,但是简单的描述原型链只需要说:


每一个构造函数构造出来的实例都会有一个_proto_属性指向其原型对象,然后原型对象实际上也是一个"对象",而对象是由Object所创建出来的实例,所以自然会指向Obect的Prototype(原型),然后Object的原型再往上指向null。这从下往上查找的“链”就是原型链。


下面有几个经典的题目,弄懂后保证你把原型链吃得透透的! 最后一题一定弄懂!!!


建议一次性把六个题目复制到一个js文件中,然后把答案删掉. (因为一次复制一个题目删一个做一个就会记得答案啦,我们要让自己忘记答案哈哈)


题目1:


function F() {
  this.a = 1;
}
var obj = new F();
console.log(obj.prototype);//打印undefined   对象只有 __proto__属性没有prototype属性,函数才有


看图; obj是F构造函数所构造的一个实例,而实例是没有prototype属性的,他是最底层的东西.


d820658645284c3299e18e34203c7ea9.png


题目2:


Object.prototype.a = 1;
var obj = {
    b: 2
};
for(var i in obj) {
    console.log(i); //能迭代出原型链里面的属性,所以会打印出 b和a
    }


拓展:


需要注意的是,虽然for…in循环可以迭代原型链上的属性,但它也会迭代对象的所有可枚举属性,包括从原型链继承的属性和对象自身的属性。如果你只想迭代对象自身的属性,可以使用Object.hasOwnProperty()方法来过滤掉原型链上的属性。例如:


for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        console.log(i);
    }
}


这样就只会打印出obj对象自身的属性b,而不会打印出原型链上的属性a。


题目3:


Object.prototype.a = 1; 
var obj = {
    b: undefined
};
console.log(obj.a);//1
console.log('b' in obj);//true  //能找到处于原型链里面的b属性
console.log(obj.hasOwnProperty('a'));//false 不是自身的属性
console.log(obj.hasOwnProperty('b'));//true  是自身的属性


题目4:


function A(){
}
function B(a){
  this.a = a;
}
function C(a){
  if(a){
  this.a = a;
  }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
 //实例对象都能访问构造函数的原型对象,可以明确的是以上3个都是能拿到a的
console.log(new A().a);//1   拿到的是原型上的a=1
console.log(new B().a);//undefined  this.a = a;将new B()这个实例对象的a属性这是为undefined,所以拿到的是undefined
console.log(new C(2).a);//2   将new C(2)这个实例对象的a属性这是为2,所以拿到的是2


题目5:


function A () {
}
A.prototype.n = 1;
var b = new A();//b实例对象已经建立原型连接
//原型对象指向被改变,不会切断b实例对象的
A.prototype = {
    n: 2,
    m: 3
}
var c = new A();//c实例对象将根据新的原型建立连接
console.log(b.n, b.m); //1 undefined  这里拿到是改变prototype之前的
console.log(c.n, c.m); //2 3  这里拿到是改变prototype之后的


题目6:


var F = function(){};
Object.prototype.a = function(){
    console.log('a')
}
Function.prototype.b = function(){
    console.log('b')
}
var f = new F();
F.a();  //打印a  对象都能访问Object.prototype中的属性和方法
F.b();  //打印b  F是函数,原型链  F => F.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
f.a();  //打印a  对象都能访问Object.prototype中的属性和方法
f.b();  //报错f.b is not a function   因f是F实例对象,原型链 f=>f.__proto__=>F.prototype=>F.prototype.__proto__ => Object.prototype


是不是有人以为f.b()会打印 b ?

如果对最后一题很懵逼的同学,可以从上往下看上面那张图,哪一个箭头连接不懂就留言吧 !


欢迎指正!!


相关文章
|
4月前
|
JavaScript 前端开发
【面试题】最详尽的 JS 原型与原型链终极详解(一)
【面试题】最详尽的 JS 原型与原型链终极详解(一)
|
4月前
|
前端开发 JavaScript
【面试题】原型与原型链 进一步理解~
【面试题】原型与原型链 进一步理解~
|
8月前
|
JavaScript 前端开发
原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。
原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。
|
4月前
|
JavaScript 前端开发 Java
【面试常见】JS继承与原型、原型链
【面试常见】JS继承与原型、原型链
|
4月前
|
设计模式 前端开发 JavaScript
【面试题】对象、原型、原型链与继承 ,你了解多少?
【面试题】对象、原型、原型链与继承 ,你了解多少?
|
4月前
|
设计模式 前端开发 JavaScript
【面试题】 对象、原型、原型链与继承?这次我懂了!
【面试题】 对象、原型、原型链与继承?这次我懂了!
|
8月前
|
JavaScript 前端开发
原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。(一)
原型与原型链,数形结合搞懂原型与原型链,真正理解原型链,面试官直呼内行。
|
10月前
|
JavaScript 前端开发
【面试常见】JS继承与原型、原型链
在 JavaScript 中,继承是实现代码复用和构建对象关系的重要概念。本文将讨论原型链继承、构造函数继承以及组合继承等几种常见的继承方式,并提供相应的示例代码,并分析它们的特点、优缺点以及适用场景。 在开始讲解 JavaScript 的继承方式之前,我们先来详细解释一下原型(prototype)、构造函数(constructor)和实例对象(instance)这三个概念。因为只有对它们有清晰的理解,才能更好地理解和应用JavaScript的继承机制。现在我们将分别介绍它们的含义和它们之间的关系。 建议点赞收藏本文章,以便日后复习~~
201 0
【面试常见】JS继承与原型、原型链
|
2月前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
62 1
|
3月前
|
存储 关系型数据库 MySQL
2024年Java秋招面试必看的 | MySQL调优面试题
随着系统用户量的不断增加,MySQL 索引的重要性不言而喻,对于后端工程师,只有在了解索引及其优化的规则,并应用于实际工作中后,才能不断的提升系统性能,开发出高性能、高并发和高可用的系统。 今天小编首先会跟大家分享一下MySQL 索引中的各种概念,然后介绍优化索引的若干条规则,最后利用这些规则,针对面试中常考的知识点,做详细的实例分析。
253 0
2024年Java秋招面试必看的 | MySQL调优面试题