写点什么

彻底深刻理解 js 原型链之 prototype,proto 以及 constructor(一)

  • 2020-10-17
  • 本文字数:2321 字

    阅读完需:约 8 分钟

彻底深刻理解js原型链之prototype,proto以及constructor(一)

前言

以下概念请花费一定的时间彻底理解,才能进行下一步,思考题一定要思考,这样才能彻底掌握原型链的知识点,教程中如果有任何的错误不足请指正!

函数对象

由 function 创造出来的函数,比如:


    function a(){};    var b=function(){};
复制代码


系统内置的函数对象


Function,Object,Array,String,Number
复制代码


只有函数对象才有 prototype 属性 ,重要的事情说三遍!


思考: js 的引用数据类型都属于函数对象吗?

普通对象

除开函数对象之外的对象都是普通对象


var b='qwe'; // b 是字符串类型,属于普通对象var c=123;; // c 是数字类型,属于普通对象
复制代码


思考:js 有五种基本类型:Undefined,Null,Boolean,Number 和 String,他们都是属于普通对象吗?

原型对象

prototype 属性也叫原型对象,主要是为了实现继承和共享属性;


可以说我们的每一次编程,内在都有原型对象来发挥着作用,如果你没有掌握原型对象的含义,那么你的 js 还没有真正的入门!


function a(){};
复制代码


首先对象 a 是由 Function 创造出来,是函数对象;那么根据我们以上的教程,a 就有了 prototype 属性,那么这个原型对象是怎么创造出来的呢? 来看下面这个例子:


var temp = new a();a.prototype=new Object();a.prototype = temp;
复制代码


那么 a 的 prototype 属性就是这样创造出来的;


思考:原型对象 prototype 属于函数对象吗?

指针 proto

JavaScript 中,万物皆对象!所有的对象 obj 都具有 proto 属性(null 和 undefined 除外),可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型


请看以下例子帮助理解:


function a(){};var obj=new a();console.log(a.__proto__===Function.prototype); //trueconsole.log(a.prototype.__proto__===Object.prototype); //trueconsole.log(obj.__proto__===a.prototype); //true
复制代码


思考一下,var obj={}; obj.prototype. proto 指向谁?

构造函数属性 constructor

假设 obj 是由函数对象 a 由 new 运算创造出来的,那么 obj 的 constructor 的属性就存放着一个对 a 的引用,通过这个构造函数,我们还可以为 a 添加其他属性和方法, 这个属性的最初设计是为了检测对象的数据类型,不过后来人们通过此属性的特性做了更多的事情


请看以下例子:


function a(){};var obj=new a();obj.constructor.b=`我是a的新的属性`;console.log(a.b); //我是a的新的属性console.log(a.constructor===Function); //trueconsole.log(a.prototype.constructor===a); //trueconsole.log(obj.constructor===a); //true
复制代码


函数 a 是由 Function 创造出来,那么它的 constructor 指向的 Function,obj 是由 new a()方式创造出来,那么 obj.constructor 理应指向 a


思考:a.prototype. proto .constructor 指向谁?

思考题解答

函数对象思考题解答

思考: js 的引用数据类型都属于函数对象吗?


引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象


那么数组,普通对象,函数对象都算是引用数据类型,引用数据类型范围包含函数对象的范围

普通对象思考题解答

思考:js 有五种基本类型:Undefined,Null,Boolean,Number 和 String,他们都是属于普通对象吗?


基本类型值:指的是保存在栈内存中的简单数据段;除开函数对象之外的对象都是普通对象,那么普通对象范围是包含基本数据类型的


事实上(函数对象,普通对象)以及(基本数据类型,引用数据类型)是在不同角度对 js 变量进行的定义

原型对象思考题解答

思考:原型对象 prototype 属于函数对象吗?


事实上 这个问题要进行分别回答:


Function.prototype 属于函数对象,其他对象的 prototype 属于普通对象


function a(){};console.log(typeof Function.prototype); // functionconsole.log(typeof a.prototype); //object
复制代码


前面说过 prototype 的创造过程


    var temp = new a();    a.prototype = temp;
复制代码


这里 temp 当然就是普通对象啦,但是看下 Function 的 prototype 创造过程


var a = new Function();Function.prototype = a;
复制代码


看明白了把,Function 的 prototype 为什么是函数对象了吧?回忆一下函数对象的定义吧!

指针 proto 思考题解答

思考一下,var obj={}; obj.prototype. proto 指向谁?


这里分步思考: 1, obj 只是一个普通对象 2, 什么类型的对象是有 prototype 属性的?当然是函数对象 3, 所以 obj 是没有 prototype 属性的 4, 所以 obj.prototype===undefined 5, 所以此题的最终问题是:undefined.proto 指向什么 6, 所有的对象 obj 都具有 proto 属性(null 和 undefined 除外)!所以答案是 js 报错(有没有一种被我坑了的感觉)

构造器 constructor 思考题解答

思考:a.prototype. proto .constructor 指向谁?


function a(){};
复制代码


这里继续分解题目: 1, a.prototype 指向 a 的一个实例,我们已经多次强调了,而且属于普通对象 2, proto 定义为:指向创造 obj 对象的函数对象的 prototype 属性,所以看下谁创造了 a.prototype,因为 a.prototype 是普通对象,类型为 object,那么是 Object 创造了它, 3, 那么显而易见 a.prototype. proto 指向了 Object.prototype 4, 那么题目简化为 Object.prototype.constructor 指向谁 5, 继续分解题目,Object.prototype 为基本对象,那么就是 Object 创造了它,那么它的 constructor 就指向了 Object


Object.prototype.constructor===Object //true
复制代码


不知道你晕不晕,我有点晕,这产生了蛋生鸡还是鸡生蛋的问题啦~


放心,还是有尽头的 :


Object.prototype.__proto__===null //true
复制代码


这个例子告诉我们是 是 null 创造了一切,这不就是易经中的:“道生一,一生二,二生三,三生万物!”


作者介绍


宜信技术学院 刘晓敏


本文转载自宜信技术学院。


原文链接


彻底深刻理解js原型链之prototype,proto以及constructor(一)


2020-10-17 14:002478

评论

发布
暂无评论
  • js 进阶手写常见函数

    无论是学习react还是vue,它们都是js的应用框架。剥去他们的壳子看到的始终是js,所以作为一个前端大厨必须要熟练掌握好js这个大勺,才能烧出一顿好菜

    2022-10-31

  • 30|JavaScript 引擎:双向通讯底层原理是什么?

    双向通讯底层原理是什么?

    2022-11-01

  • 聊聊前端面试中的 js 同步与异步问题

    我本来是打算写一篇co源码精读(为啥读co,因为它短),然鹅发现自己存在一系列基础问题没有搞透彻,打算写一个js基础系列文章,总结自己的理解(copy),希望与你在学习路上一同进步。首先问问自己当面试官问到js中的同步和异步,这个问题该怎么回答?理解一个问

    2022-10-06

  • 前端 js 手写题经常忘,记录一下

    方法1:序列化 JSON.stringify + 正则匹配

    2022-09-23

  • JS 事件,你真的懂吗(捕获,冒泡)?

    说到js事件大家肯定都知道,那么今天讲一点大家不知道的(假设大家不知道🐶)。所有的js事件都会分为两个阶段捕获和冒泡。那么问题来了,我们通常看到的事件都是直接触发之后就执行了,那么我们怎么才能看到事件的捕获和冒泡都是怎么进行的呢,这里给大家准备

    2022-10-22

  • js 函数式编程讲解

    是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。

    2022-10-27

  • 08|深入理解继承、Delegation 和组合

    通过JavaScript做到代码复用的几种核心思想和方法。

    2022-10-06

  • 面试官:能用 JavaScript 手写一个 bind 函数吗

    经常会看到网上各种手写bind的教程,下面是我在自己实现手写bind的过程中遇到的问题与思考。如果对于如何实现一个手写bind还有疑惑的话,那么可以先看看上面两篇文章。

    2023-02-21

  • JavaScript 刷 LeetCode 拿 offer-js 版字典

    与集合类似,字典也是一种存储唯一值的数据结构,但它是以键值对的形式来存储。

    2022-11-15

  • 从这两道题重新理解,JS 的 this、作用域、闭包、对象

    日常开发中,我们经常用到this。例如用Jquery绑定事件时,this指向触发事件的DOM元素;编写Vue、React组件时,this指向组件本身。对于新手来说,常会用一种意会的感觉去判断this的指向。以至于当遇到复杂的函数调用时,就分不清this的真正指向。

    2023-01-02

  • js 函数柯里化 - 面试手写版

    用我自己的话来总结一下,函数柯里化的意思就是你可以一次传很多参数给curry函数,也可以分多次传递,curry函数每次都会返回一个函数去处理剩下的参数,一直到返回最后的结果。

    2022-10-17

  • 深入理解对象的私有和静态属性

    深入了解JavaScript的对象构建和面向对象的编程模式。

    2022-10-04

  • 22|结构型:Vue.js 如何通过代理实现响应式编程

    Vue.js的一个很大的特点就是用到了如今流行的响应式编程(Reactive Programming)。那它是怎么做到这一点的呢?这里面离不开代理模式,

    2022-11-08

  • js 对象和原型、原型链的关系

    JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个概念一知半解,碰到问题靠“猜”,却不理解它的规则!

    2022-10-21

  • 09|面向对象:通过词法作用域和调用点理解 this 绑定

    学习this的绑定,一个和函数式中的closure有着同等重要性的概念。

    2022-10-08

  • js 进阶手写常见函数

    无论是学习react还是vue,它们都是js的应用框架。剥去他们的壳子看到的始终是js,所以作为一个前端大厨必须要熟练掌握好js这个大勺,才能烧出一顿好菜

    2022-10-03

  • 细说 js 变量、作用域和垃圾回收

    基本类型和引用类型

    2022-10-17

  • Vue 入门指北——css 中的 js 变量

    最近项目演示,手上没什么活,正好借着闲下来的功夫,看了看vue3的文档,发现vue3对vue3的支持加强了。以前总是想着,如果js中的变量能直接,css中使用,那是多么一件美妙的事情啊,而且优雅。而在这次的vue3里面支持这么做了,你可以随意使用js中的变量,只

    2022-09-27

  • js 函数式编程讲解

    是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。

    2022-10-03

  • 11|通过 JS 引擎的堆栈了解闭包原理

    如果说一个函数“出生”的地方是作用域,从出生到被回收的“一生”是它的生命周期,那么闭包则可以突破这种空间和时间上的限制,那它是怎么做到这种突破的呢?

    2022-10-13

发现更多内容

硅谷来信:快速行动,Facebook、Quora等成功的“神器”!

博文视点Broadview

入门 Polkadot 平行链开发,看这一篇就够了

One Block Community

区块链

秘乐短视频挖矿系统开发详情

开发微hkkf5566

【7.29-8.5】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

Apache APISIX Ingress v1.5-rc1 发布

API7.ai 技术团队

APISIX kubenetes Ingress Controller

深入理解 Istio 流量管理的超时时间设置

万猫学社

云原生 istio envoy Istio流量管理

这份阿里强推的并发编程知识点笔记,将是你拿大厂offer的突破口

了不起的程序猿

数据库 高并发 java程序员 大厂面试 java;

创建一个 Dapp,为什么要选择波卡?

One Block Community

区块链

全国独家 | 上海线下面授大规模敏捷LeSS认证 | 2022年12月8-10日

ShineScrum

less 大规模敏捷 LeSS认证 大规模敏捷LeSS

DFINITY 基金会创始人谈熊市沉浮,DeFi 项目该何去何从

TinTinLand

区块链

语音社交软件开发——充分发挥其价值

开源直播系统源码

软件开发 直播系统源码 语音聊天

RT-Thread记录(一、RT-Thread 版本、RT-Thread Studio开发环境 及 配合CubeMX开发快速上手)

矜辰所致

RT-Thread 8月月更

企业的数字化转型到底是否可以买来?

雨果

数字化转型

数据中台建设(十):数据安全管理

Lansonli

大数据 数据中台 8月月更

多业务模式下的交易链路探索与实践

转转技术团队

中台 状态机 FSM

STM32+ULN2003驱动28BYJ4步进电机(根据圈数正转、反转)

DS小龙哥

8月月更

有多一只“手”的机器狗出没?就在昇腾AI开发者创享日·南京站

科技热闻

Go编译原理系列6(类型检查)

书旅

Go 源码 后端

双因子与多因子身份验证有什么区别?

SEAL安全

身份验证

高质量 DeFi 应用构建指南,助力开发者玩转 DeFi Summer

TinTinLand

区块链

JS逆向入门学习之回收商网,手机号码简易加密解析

梦想橡皮擦

Python 爬虫 8月月更

导火索:OAuth 2.0四种授权登录方式必读

知识浅谈

8月月更

牛刀小试基本语法,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本语法和变量的使用EP02

刘悦的技术博客

golang 语言 语言 & 开发 教程分享 #go

即刻报名|Apache Kylin X Apache DolphinScheduler:大数据底座的构建和展望

Kyligence

数字化转型 数字分析 数据调度

HDD杭州站•ArkUI让开发更灵活

HarmonyOS开发者

HarmonyOS

WindTerm:新一代开源免费的终端工具,GitHub星标6.6k+,太酷了!

沉默王二

GitHub 终端工具

数据治理体系演进简介

网易数帆

大数据 数据治理 元数据 数据标准

告白数字化转型时代:麦聪软件以最简单的方式让企业把数据用起来

雨果

数字化转型

电竞、便捷、高效、安全,盘点OriginOS功能的关键词

Geek_2d6073

2000多字教你三招在Linux中找出大文件,最后一个命令简直太简单了!

wljslmz

Linux 签约计划第三季 8月月更

Python开启虚拟环境

技术小生

8月月更 Python虚拟环境

彻底深刻理解js原型链之prototype,proto以及constructor(一)_编程语言_刘晓敏_InfoQ精选文章