前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Javascript原型链您了解多少

Javascript原型链您了解多少

作者头像
切图仔
发布2022-09-08 15:07:36
1780
发布2022-09-08 15:07:36
举报
文章被收录于专栏:生如夏花绚烂

JS面向对象中的原型 每一个函数都有一个属性 即原型对象(显式原型:prototype)这个原型对象默认指向一个Object空对象,同时每一个原型对象(prototype)都有一个属性(constructor)又指向构造函数(构造函数和它的原型对象相互引用),同时每一个实例对象又有一个__proto__属性(隐式原型),这个属性指向其构造函数的原型对象 (Fn.prototype===fn.__proto__)。

需要注意的是每个函数也有一个隐式属性__proto__,因为函数是Function的实例

理解上面概念,引入“原型链” 如下新建一个构造函数

代码语言:javascript
复制
function Student(name,sex,age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
在这里插入图片描述
在这里插入图片描述

打印这个构造函数,发现其具有prototype属性,这个属性就是构造函数的原型对象,同时这个原型对象有具有一个属性constructor属性,这个属性指向构造函数

实例化构造函数

代码语言:javascript
复制
var stu1 = new Student('te','m',12);
 console.dir(stu1);
在这里插入图片描述
在这里插入图片描述

打印结果,印证上面所说的每一个对象又有一个__proto__属性,这个属性是指向构造函数的原型对象的所以proto ==构造函数的prototype

代码语言:javascript
复制
 console.log(stu1.__proto__ === Student.prototype)
 //返回true

综上我们可以得出 构造函数 原型对象 以及对象之间的关系 如图

在这里插入图片描述
在这里插入图片描述

方便理解为每个步骤列图 1.当创建构造函数时 此时在栈区创建了一个函数名(Student)存储的是地址值(0x123)指向堆区的Function对象,这个对象会有一个prototype属性,指向默认的空Object对象

2.当实例化构造函数时 在栈取创建了一个stu1存储的是地址值(0x345)执行堆区的Student实例对象,这个对象会生成一个隐式原型__proto__属性,这个属性也执行prototype指向的对象(__proto__=Student.prototype)

3.当为原型对象添加方法时

对象通过构造函数创建,而每一个对象有一个__proto__属性,这个属性是指向原型对象的,而每一个原型对象又有一个constructor属性,这个属性指向构造函数,上面说到每一个构造函数具有一个prototype属性,这个属性就是原型对象 由此可以得到一个简单得三角关系。 如果你仔细观察可以发现原型对象也有一个__proto__属性,这并不奇怪,因为每一个对象都有一个__proto__属性这个属性是指向他构造函数的原型对象。 查看原型对象的指向

在这里插入图片描述
在这里插入图片描述

可以看到原型对象的__proto__属性(这个属性指向Object的原型对象)里面的constructor属性指向其构造函数Object 那么原型对象也是由构造函数创建,这个构造函数就是Object。上面说到只要是对象就会有一个__proto__属性,这个属性指向构造函数的的原型对象,那么Object的原型对象的原型对象又是什么呢?

代码语言:javascript
复制
 var stu1 = new Student('te','m',12);
 var o = stu1.__proto__;
 console.log(o);//构造函数的原型对象
 console.log(o.__proto__.__proto__);//Object的原型对象的原型对象
在这里插入图片描述
在这里插入图片描述

可以看到Object的原型对象的原型对象为空null那么null有原型对象吗,会不会一直循环下去?

代码语言:javascript
复制
   console.log(o.__proto__.__proto__.__proto__);//null的原型对象
在这里插入图片描述
在这里插入图片描述

抛出异常,说明最顶层的原型对象就是null,因此我们可以得出一个简单的原型链图

在这里插入图片描述
在这里插入图片描述

我们通过构造函数创建一个对象,因为每一个对象有一个__proto__属性,这个属性就指向该对象构造函数的原型对象,由于原型对象也有一个__proto__属性,这个属性指向原型对象的原型对象,我们可以看到原型对象的原型对象的构造函数为Object而原型对象是具有__proto__属性的,而Object的原型对象的原型对象指向null所以我们说最顶层的原型对象为null

说了那么多根据原型链我们可以得出对象查找/设置属性和方法的规则

结论

查找:对象在调用属性或方法时,会先在当前对象查找是否有相关属性或方法 如果没有就在当前对象的构造函数的原型对象上查找,如果还是没有则继续在原型对象的原型对象上查找直到指向null这就是我们所说的原型链。 如下

代码语言:javascript
复制
function Student(name,sex,age){
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.method = function(){
            console.log(123)
        }
    }//构造函数
    Student.prototype.method=function(){
        console.log(321)
    }

   var stu1 = new Student('te','m',12);
   stu1.method()

我们分别在原型对象和构造函数中写入了相同的方法,结果输出123 如果我们将构造函数中的method方法去掉则会调用原型对象上的方法输出321 同时我们可以原型链的查找规则使用Object中的属性或方法,以toString为例

代码语言:javascript
复制
 console.log(stu1.toString());
 //返回[object Object]字符串

设置:对象在设置属性/方法时,如果当前对象没有该属性或方法,则重新在当前对象创建一个同名属性/方法,并不会影响原型链上具有的属性或方法

代码语言:javascript
复制
function Student(name,sex,age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }//构造函数
    Student.prototype.method=function(){
        console.log(123);
    }

   var stu1 = new Student('te','m',12);
   stu1.method=function(){
       console.log(321)
   }
  
   var stu2 = new Student('w','w',13);
   stu1.method();
   stu2.method()
   // console.dir(
在这里插入图片描述
在这里插入图片描述

可以看到stu1并没有修改原型链上的方法

instanceof是如何判断的

表达式 A instanceof B 如果B函数的显示原型对象在A对象的原型链上,返回true,否在返回false

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-04-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结论
    • instanceof是如何判断的
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档