彻底深刻理解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); //true
console.log(a.prototype.__proto__===Object.prototype); //true
console.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); //true
console.log(a.prototype.constructor===a); //true
console.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); // function
console.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:00 2

评论

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

【高并发】面试官:讲讲什么是缓存穿透?击穿?雪崩?如何解决?

冰河

缓存 面试 穿透 击穿 雪崩

spark总结

03 Spring Security 入门实例

哈库拉玛塔塔

Spring Boot kotlin spring security

不使用Raft算法,就能简单做集群leader选举

架构师修行之路

分布式 架构师

浮点数的秘密

C语言与CPP编程

c c++ 编程语言 浮点数

华为与第四范式,正在酝酿一个帮企业跳出AI悖论的“秘密计划”

脑极体

从一段 Dubbo 源码到 CPU 分支预测的一次探险之旅

yes的练级攻略

dubbo cpu

架构师训练营第十四周总结

张明森

智能商业时代的思考(二)网络协同抓住用户

刘旭东

微信 商业价值 数据智能 网络协同 商业智能

区块链激励层——区块链生态建设的驱动力量

CECBC区块链专委会

区块链技术 驱动力量

认证、授权、鉴权和权限控制

哈库拉玛塔塔

spring security 用户权限 鉴权 权限

Spring Security 主要类解释

哈库拉玛塔塔

springsecurity

第五周作业

Vincent

极客时间 极客大学

第五周总结

Vincent

极客时间 极客大学

简述C语言宏定义的使用

C语言与CPP编程

c c++ 编程语言

Mysql学习笔记:InnoDB事务和ACID模型

马迪奥

MySQL innodb

HashMap将cpu打满始末

林昱榕

hashmap 线程安全 cpu 100% cpu飙满

一文带你了解微服务架构和设计(多图)

Phoenix

架构 分布式 微服务

导致系统不可用原因及密码验证

ARTS Week16

时之虫

ARTS 打卡计划

以大数据为依托提升基层治理效能

CECBC区块链专委会

大数据 信息化管理

布式系统消息异常该何去何从

架构师修行之路

分布式 异步

洗牌算法

C语言与CPP编程

c c++ 算法 编程语言

计算机的时钟(三):向量时钟

ElvinYang

CString 类的线程不安全问题

C语言与CPP编程

c c++ 编程语言

安全相关总结

C语言指针详解

C语言与CPP编程

c c++ 编程语言 指针

ARTS打卡Week 12

teoking

区块链应用层——生态体系的上层建筑

CECBC区块链专委会

区块链技术 生态体系

记录问题 INSERT INTO table ... SELECT ... FROM dual WHERE not exists (...)问题

浅^安

sql SQL语法 sql查询

重新学习了一遍ThreadLocal

熊斌

学习总结

Milvus Community Conf 2020

Milvus Community Conf 2020

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