写点什么

彻底深刻理解 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:002495

评论

发布
暂无评论
  • 细说 js 变量、作用域和垃圾回收

    基本类型和引用类型

    2022-10-17

  • JavaScript 刷 LeetCode 拿 offer-js 版字典

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

    2022-11-15

  • js 进阶手写常见函数

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

    2022-10-03

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

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

    2022-09-27

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

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

    2022-11-08

  • js 函数式编程讲解

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

    2022-10-27

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

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

    2022-10-06

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

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

    2022-09-23

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

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

    2022-10-17

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

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

    2022-10-08

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

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

    2022-10-04

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

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

    2022-11-01

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

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

    2022-10-22

  • js 函数式编程讲解

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

    2022-10-03

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

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

    2023-01-02

  • js 进阶手写常见函数

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

    2022-10-31

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

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

    2023-02-21

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

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

    2022-10-21

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

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

    2022-10-06

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

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

    2022-10-13

发现更多内容

OLAP计算引擎怎么选?

数据社

大数据 OLAP 5月日更

Python自动打印文件

IT蜗壳-Tango

IT蜗壳教学 5月日更

作为最好用的可观测平台,如何监控 Grafana

耳东@Erdong

Grafana Prometheus 5月日更

ThreadLocal不好用?那是你没用对!

王磊

Java 后端 多线程 ThreadLocal 5月日更

声网、新东方、伴鱼英语的音视频技术解读

Jessie

音视频 视频消音

Golang 工作区和 GOPATH

escray

学习 极客时间 Go 语言 5月日更

一文带你读懂PyQt:用Python做出与C++一样的GUI界面应用程序

老猿Python

深度剖析 | 关于数据锁定和读取一致性问题

VoltDB

数据库 数据分析 5G

Python 包管理

若尘

Package Python编程 5月日更

怎样做好服务提供方

程序员架构进阶

架构设计原则 服务化 28天写作 5月日更

给Java小白,整理一套能上手的简单编程算法题!!!

小傅哥

Java 程序员 数据结构 算法 小傅哥

网络攻防学习笔记 Day12

穿过生命散发芬芳

5月日更 网络攻防

xSocket框架接入需实现的接口

风翱

xSocket 5月日更

Arthas-技术专题-使用指南

洛神灬殇

Arthas 5月日更

VMWare中Ubuntu网络配置

进击的梦清

Linux 运维 vmware 网络配置

如何让消息队列达到最大吞吐量?

万俊峰Kevin

微服务 消息队列 Queue Go 语言

华为云官网负责人明哥:我们是如何做到门面不倒,8个月挑战业界翘楚?

华为云开发者联盟

JavaScript node.js Serverless 云原生 大前端

Dubbo 本地调用

青年IT男

dubbo

追寻软件定义的梦想汽车

车骑

自动驾驶 智能汽车 软件定义汽车 汽车制造

不忘过去,不畏将来

小天同学

5月日更 汶川地震 不忘过去

最近又有出什么新电影,要不要停泊片刻,与好友相约一起来去看呢?

叶小鍵

算法训练营 - 学习笔记 - 第六周

心在飞

kotlin基础

ES_her0

5月日更

cri-o 技术探秘2

xumc

找Matlab代码,看这一篇就够了

攻城先森

matlab 工具分享 5月日更

【LeetCode】停在原地的方案数Java题解

Albert

算法 LeetCode 5月日更

零基础学习 NLP-DAY3

Qien Z.

动态规划 nlp 5月日更

无常中的僵硬与柔软

zhoo299

随笔杂谈 教育 生命 5月日更

「学习笔记」《02 | 第一个程序:教你输出彩色的文字》之二

Nydia

学习

鸿蒙系统之Codelab布局组件尝鲜

liuzhen007

华为 鸿蒙 5月日更

精选面试题教你应对高级iOS开发面试官(提供底层进阶规划蓝图)

程序员 移动开发 ios开发

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