原生js中的`__proto__`和prototype、原型链 解析

__proto__和prototype是原生js中比较重要的一环,接下来我从函数对象,两个方面,谈谈我的理解

Function函数解析

js函数是原生js比较重要的一环,先来谈谈我对函数的理解,

js是函数式编程,最重要的就是prototypeconstructor

prototype原型对象

首先明确一点,每个函数都有prototype属性,prototype指向了一个对象,这个对象就叫原型对象。

constructor构造器

每个原型对象有一个constructor属性,指向了构造函数本身,

光说还是有点难懂,我先上图

微信截图_20200229193425.png

// 代码
function foo() {}
// 原型
console.log(foo.prototype); // {constructor: ƒ}
// 构造器
console.log(foo.prototype.constructor); // ƒ foo() {}

上面代码和图可知foo的prototype属性指向一个对象,然后对象有一个属性constructor 又指向了 foo构造函数,看下图:

微信截图_20200229194518.png

就是这样的关系,不过这个不能单独理解,且听我下面讲完__proto__属性

对象的__proto__属性

每个对象都有__proto__属性指向构造函数的prototype属性;

怎么验证呢?

这里首先要先说下创建对象的三种方式了

1、对象字面量(常用)

var _obj = {};

2、构造函数Object

var _obj = new Object();

3、通过Object.create(prototype) 初始化对象;

var _o = {};
var _obj = Object.create(_o);

然后 其实这三种方式都调用了Object函数,生成的对象的__proto__属性,都指向了Object函数的prototype属性

微信截图_20200229202819.png

var _obj = {};
console.log(_obj); 

// _obj.__proto__ 指向了Object的原型对象{……}
console.log(_obj.__proto__ === Object.prototype); // true

这样我们验证出来所有对象都有__proto__属性,指向了构造函数的原型对象

然后对象的__proto__和函数的prototype有什么关系呢?

实例化对象验证

我们都知道实例化会生成一个对象,对象都有__proto__属性,指向原型对象,

那就意味着函数的prototype属性,和实例化的__proto__指向同一个对象,验证下。

// 1、__proto__指向的是【构造函数的prototype属性】
function fnxx(){}

// new生成一个实例对象
var _xx = new fnxx();

// 对象的__proto__和函数的prototype
console.log(_xx.__proto__ === fnxx.prototype); // true

上面代码跑了之后,结果为true,说明咱们验证是正确的😄!

然后这有什么用呢?

看下面

原型链

js在创建对象的时候都有__proto__内置属性,用于指向创建它函数对象的原形对象prototype

没错这就是原型链。

_xx.__proto__.__proto_…… 沿着__proto__属性逐层向下查找,这就是一个最简单的原型链,继承的话也是这样一层层向下找。

在深入理解

js中万物皆对象,Function也是对象,所有对象指向了Object对象 ,也就是说Object对象是所有对象的基类;

Object的__proto__属性指向null;

验证下

function fnxx(){}

// 2、对象的__proto__
console.log(fnxx.prototype.__proto__); // 指向Object构造函数的原型对象

console.log(fnxx.prototype.__proto__ === Object.prototype); // true

// Object对象是所有js对象的基类
console.log(Object.prototype.__proto__); // null

至此一个完整的链条就很清晰了;

函数都有一个prototype属性,指向原型对象,原型对象有constructor 属性,指向了构造函数本身。

对象有__proto__属性,指向创建它的原型对象,__proto__用来实现原型链查找,是继承中关键的一环。

js中最重要的两个概念__proto__和prototype这里就讲清楚了,大家有啥不懂的,可以评论留言。

接下来我再出几篇,关于继承,还有prototype原型模式的应用。

1 篇内容引用
21 声望
0 粉丝
0 条评论
推荐阅读
原生js实现类jq框架
前言 今天来实现一个简单的js框架,类似jq的功能,实现了增减class,增减属性,链式调用,合并对象等功能, 更加深入理解下js原型prototype的应用,是之前承诺的原型模式应用的文章,欢迎评论交流 初始化方法 {代...

yuanfa247阅读 1.5k

ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -> Preference-> Settings(如果装了中文插件包应该是 文件 -> 选项 -> 设置),搜索 eslint,点击 Edit in setting.json

谭光志34阅读 20.8k评论 9

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城32阅读 7.3k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco24阅读 2.3k评论 3

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 2k

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.9k评论 3

封面图
Vue2 导出excel
2020-07-15更新 excel导出安装 {代码...} src文件夹下新建一个libs文件夹,新建一个excel.js {代码...} vue页面中使用 {代码...} ===========================以下为早期的文章今天在开发的过程中需要做一个Vue的...

原谅我一生不羁放歌搞文艺14阅读 20.1k评论 9

21 声望
0 粉丝
宣传栏