原型链prototype、__proto、constructor的那些问题整理

2024-04-27 09:28

本文主要是介绍原型链prototype、__proto、constructor的那些问题整理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

再了解原型链之前,我们先来看看构造函数和实例对象的打印结构

- 函数

这里我们定义一个构造函数Fn,然后打印它的结构吧

function Fn(){}
console.dir(Fn)

控制台得到结构
在这里插入图片描述
从上面结构我们能看的出来,函数有两种原型,一种是作为函数特有的原型:prototype,另一种是作为对象的__proto__类型(就是上图那个[[Prototype]],__proto__是浏览器自己填充的,新浏览器都能看到,我的浏览器版本低,还看不到哈,先这么写)

我们先来看做为函数特有属性的prototype哈,我们展开看看
在这里插入图片描述
可以看到函数的prototype上有一个构造函数constructor和一个__proto__属性,这个constructor实际上就是函数本身,另外一个__proto__呢,你看它的值是一个对象Object呢.也就是说函数的prototype的__proto__指向Object的prototype,我们下面运行看看是不是这样呢?

Fn.prototype.__proto__ === Object.prototype.    // true

我们运行结果果然和预期一样返回了true.

我们再来看函数的另外一个原型__proto__,我们展开它

在这里插入图片描述
我们看到函数的__proto__是一个Function,我们猜想这个函数的__proto__指向Function的prototype,我们来运行看看

Fn.proto === Function.prototype. // true

果然,和预期一样,所以我们根据上面的一些结果有了总结

1、函数有两个原型,一个是作为函数特有的prototype,另一个是作为对象的__proto__
2、函数的 prototype中constructor就是函数本身
3、函数的 prototype中__proto__属性指向Object的prototype
4、函数的__proto__指向Function的prototype

  • 对象

现在我们根据上面的构造函数,我们实例化一个对象来看看结构

let obj = new Fn()
console.dir(obj)

我们来看看obj对象的结构

在这里插入图片描述
可以看到上面的obj对象只有一个__proto__原型,我们展开看似乎和它的构造函数的prototype长的一样呢,我们运行看看

obj.proto === Fn.prototype. // true

果然,结果和我们预期一样

所以我们有了结论:

对象只有一条__proto__原型,并且对象的原型__proto__就指向构造函数的prototype

  • constrctor

我们再回过头来看刚刚构造函数中那个constrctor,上面你看实例对象obj可以找到构造函数的prototype,而这个prototype上就有constrctor,所以由此得出根据构造函数实例得到的每一个实例对象,都能找到它的构造函数

我们来运行看看哈

 obj.__proto__.constructor    // ƒ Fn(){}

没有问题,和预期一样,这么看,我们现在就可以把上面写法精简一下,因为对象上的属性和方法,自己上面没有,就会去它的原型链上面去找,也就是对象会有原型的继承

根据这个原则,我们把上面运行的就能精简一下了

obj.constructor.   //. ƒ Fn(){}

我们就这样就找到了构造函数了.

这里找到构造函数的目的是啥呢,除了用它来实例化对象之外,还能给原型链添加公共的属性和方法,供所有的实例对象调用.

我们来看一段代码

obj.constructor.prototype.sayHello = function(){ console.log("hello")}
obj.sayHello().  // hello
let obj2 = new obj.constructor()
obj2.sayHello(). // hello

从上得出,我们可以通过constructor的prototype添加通用的属性和方法.

有人提出干嘛那么麻烦,我们通过对象的__proto__直接添加属性和方法不是更好嘛,代码更精简,我们来看看

obj.proto.name = “zhang”
obj.name. // “zhang”
obj.name // “zhang”

我们看到我们通过对象的__proto__也能添加构造函数的公用属性和方法,所以,这样写到底有没有问题呢?

其实这样写虽然在浏览器运行没有问题,但是上面我们提到过,__proto__这个属性是浏览器厂商自己内置的,有的浏览器是不支持的,所以使用constructor更可靠一点。

就先整理到这里

这篇关于原型链prototype、__proto、constructor的那些问题整理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940126

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py

Mysql中深分页的五种常用方法整理

《Mysql中深分页的五种常用方法整理》在数据量非常大的情况下,深分页查询则变得很常见,这篇文章为大家整理了5个常用的方法,文中的示例代码讲解详细,大家可以根据自己的需求进行选择... 目录方案一:延迟关联 (Deferred Join)方案二:有序唯一键分页 (Cursor-based Paginatio

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给