写点什么

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

2020 年 10 月 17 日

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

评论

发布
暂无评论
发现更多内容

Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车

newbe36524

Docker Reactive ASP.NET Core

阿里四面你都知道吗?

java金融

Java 程序员 互联网 阿里 简历

JVM中栈的frames详解

程序那些事

JVM 堆栈 性能调优 JIT GC

Linux 进程必知必会

cxuan

Linux 操作系统

工厂方法模式

Leetao

Python 设计模式 工厂方法模式

技术选型课程小结

行下一首歌

极客大学架构师训练营

如何学习Visual Studio Code

博文视点Broadview

学习 读书笔记 vscode 能力提升 编辑器

华为云FusionInsight MRS通过信通院大数据能力评估 单集群突破2万+规模

FI洞见

大数据 FusionInsight MRS 华为云

redis系列之——分布式锁

诸葛小猿

Java redis 分布式 分布式锁

Scala中如何优雅地实现break操作

吴慧民

scala

聊聊Spring的IOC以及JVM的类加载

小隐乐乐

浅析 VO、DTO、DO、PO 的概念、区别和用处!

Java小咖秀

学习 设计模式 模型 经验分享

依旧乐观的李彦宏,十年寻光的百度AI

脑极体

统一物品编码破解追溯“断链”困局

CECBC区块链专委会

开发者必备——API设计问题

Noneplus

鲲鹏说:高考之路你们走,高考阅卷我来守

脑极体

ArrayList源码阅读

慌张而黑糖

ArrayList 源码阅读

typora设置图片自动上传,实现快速发文章

诸葛小猿

Typora PicGo gitee 上传图片

重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」

小傅哥

设计模式 小傅哥 重构 代码优化 访问者模式

架构师训练营-作业5

紫极

毕业三年了,我开始明白为什么说三年是一个坎

鄙人薛某

程序员 程序人生 程序员成长 职场回顾

这样的二维码,你见过吗?

诸葛小猿

Java Python 后端开发 二维码 myqr

架构师训练营第六周总结

Melo

极客大学架构师训练营

kubernetes集群安装(二进制)

小小文

Kubernetes 容器 容器技术

如何通过DDD构建一辆汽车

Winfield

领域驱动设计 DDD

信创舆情一线--5省发布区块链发展计划

统小信uos

区块链 舆情

分布式缓存与消息队列

紫极

golang内存对齐

PONPON

go golang go内存对齐

啃碎并发(七):深入分析Synchronized原理

猿灯塔

Java

数据分析师成长体系漫谈-数仓模型设计

analysis-lion

学习 数据仓库 数据分析 随笔杂谈

数据库分片

Arthur

飞猪Flutter技术演进及业务改造的实践与思考

飞猪Flutter技术演进及业务改造的实践与思考

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