深入了解JavaScript中基于原型(prototype)的继承机制
原型
前言
继承是面向对象编程中相当重要的一个概念,它对帮助代码复用起到了很大的作用。
正文
Brendan Eich在创建JavaScript时,没有选择当时最流行的类继承机制,而是借鉴Self,用到了基于原型(prototype)的继承机制,这导致了JavaScript在继承机制方面与Java、C++等基于类继承机制的语言有着显著的区别。
其具体在于—C++的多重继承、Java的继承和接口实现中都包含"类"的概念,它们倾向于在创建对象之前[1]已经规定了对象需要继承的类和实现的接口,并且使用类与类之间的继承方式。
而在JavaScript中没有"类"的概念,在对象之后所继承的对象也是可以发生动态变化的,并且使用的是对象与对象之间的继承方式。
如果将JavaScript中由string,number,bigint,boolean,null,undefined,symbol组成的基础类型与其对应的值都按下不表,余下的引用类型与其对应的值将都存在着__proto__[2]属性,指向继承的原型对象[3]。
与__proto__存在于每个对象中不同,prototype属性只存在于函数中,在默认的的情况下所有对象的__proto__属性的值与其构造函数下的prototype属性的值是一致的。
let obj = new Object();
obj.constructor === Object;//true
//obj的__proto__属性的值与obj的构造函数的prototype属性的值指向同一块堆内存
obj.__proto__ === obj.constructor.prototype;//true
obj.__proto__ === Object.prototype;//true

所有函数的构造函数都指向Function:
Object.constructor === Function;//true
//Object的__proto__属性的值与Object的构造函数的prototype属性的值指向同一块堆内存
Object.__proto__ === Object.constructor.prototype;//true
Object.__proto__ === Function.prototype;//true
Function.constructor === Function;//true
//Function的__proto__属性的值与Function的构造函数的prototype属性的值指向同一块堆内存
Function.__proto__ === Function.constructor.prototype;//true
Function.__proto__ === Function.prototype;//true

Function的prototype属性的原型指向Object.prototype:
Object.prototype === Function.prototype.__proto__;//true

不单单是 Function 的prototype属性的原型指向 Object.prototype ,几乎所有的函数[4]的prototype属性的原型指向 Object.prototype ,从V8的测试代码中可见一斑:

最后,位于原型顶点的是Object.prototype.__proto__,它指向 null:
Object.prototype.__proto__ === null;//true
Object.prototype.constructor === Object;//true

根据以上逻辑画的原型指向图:

为了加深理解,我将再定义一个构造函数:
function Person(){
}
Person.constructor === Function;//true
Person.__proto__ === Person.constructor.prototype;//true
Person.__proto__ === Function.prototype;//true

通过新定义的构造函数创建对象:
let person = new Person();
person.constructor === Person;//true
person.__proto__ === person.constructor.prototype;//true
person.__proto__ === Person.prototype;//true

根据以上逻辑画的最终的原型指向图:

结尾
了解JavaScript中基于原型(prototype)的继承机制的重点在于捋清楚Object与Function的__proto__、constructor、prototype属性的指向关系,再进一步了解Object和Function各自对应的值以及通过Function对应的值创建出来的对象的__proto__、constructor、prototype属性的指向关系,就大功告成了。
听起来可能有一点点绕,最好是动手画一下图,以后忘记的时候看一下自己画的图就又想起来了。
最后,本人才疏学浅,如有错误之处,还望各位不理赐教。
深入了解JavaScript中基于原型(prototype)的继承机制的更多相关文章
- JavaScript中的原型prototype和__proto__的区别及原型链概念
问题 初学js的同学,总是搞不清楚js中的原型是什么东西,看着控制台打印出来的一串串__proto__,迷惑不已. 例如我定义一个Person,创建一个实例p,并打印实例. function Pers ...
- JavaScript中的原型链和继承
理解原型链 在 JavaScript 的世界中,函数是一等公民. 上面这句话在很多地方都看到过.用我自己的话来理解就是:函数既当爹又当妈."当爹"是因为我们用函数去处理各种&quo ...
- JavaScript之基于原型链的继承
本文介绍下js的OOP中的继承. 上图的要点为:Foo函数在创建时会自动生成内置属性prototype,而typeof Foo.prototype是object类型的. 上图的要点为:Foo.prot ...
- 【转】JavaScript中的原型和继承
请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans ...
- 理解JavaScript中的原型继承(2)
两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...
- javascript中的原型继承
在Javascript面向对象编程中,原型继承不仅是一个重点也是一个不容易掌握的点.在本文中,我们将对Javascript中的原型继承进行一些探索. 基本形式 我们先来看下面一段代码: <cod ...
- 图解JavaScript中的原型链
转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...
- 前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则
理解原型设计模式以及 JavaScript中的原型规则(原文地址) 1.原型对象:我们创建的每一个函数(JavaScript中函数也是一个对象)都有一个原型属性 prototype,原型属性实质上是一 ...
- JavaScript中的原型、原型链、原型模式
今天,咱来聊聊JavaScript中的原型跟原型链 原型跟原型模式 这一块的知识,主要是设计模式方面的. 首先,我们知道JavaScript是面向对象的.既然是面向对象,那它自然也有相应的类跟对象等概 ...
随机推荐
- 风炫安全WEB安全学习第十八节课 使用SQLMAP自动化注入(二)
风炫安全WEB安全学习第十八节课 使用SQLMAP自动化注入(二) –is-dba 当前用户权限(是否为root权限) –dbs 所有数据库 –current-db 网站当前数据库 –users 所有 ...
- Error: Could not open input file: /usr/java/jdk1.7.0_07/jre/lib/jsse.pack
[root@localhost ~]# rpm -ivh jdk-7u7-linux-i586.rpm Preparing... ################################### ...
- 最新详解android自动化无障碍服务accessibilityservice以及高版本问题_1_如何开启获得无障碍
前言 无障碍服务accessibilityservice是什么 简单来说 无障碍服务就是一个为残障人士 尤其是视觉障碍人士提供的一个帮助服务.具体就是可以识别控件 文字 可以配合语音助手 操作和 使用 ...
- CTFHub - Web(四)
最近又是每天忙到裂开,,,淦 xss: 反射型: 1.第一个输入框与下面Hello后的内容相同,猜测可以通过该输入,改变页面内容. 测试语句: <script>alert(1)</s ...
- MySQL下载与安装教程
一,下载篇 1,首先访问MySQL官网下载页,https://dev.mysql.com/downloads/mysql/ 如果是MAC系统,操作系统请选择macOS,Windows则选择Window ...
- [Usaco2008 Open]Roads Around The Farm分岔路口
题目描述 约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土地.她们将沿着一条路走,一直走到三岔路口(可以认为所有的路口都是这样的).这时候,这一群奶牛可能会分成两群,分别沿 ...
- FLask的偏函数应用
偏函数 实际上,偏函数主要辅助原函数,作用其实和原函数差不多,不同的是,我们要多次调用原函数的时候,有些参数,我们需要多次手动的去提供值.而偏函数便可简化这些操作,减少函数调用,主要是将一个或多个参数 ...
- Spring Security 实战干货:分布式对象SharedObject
1. 前言 在上一篇我们对AuthenticationManager的初始化的细节进行了分析,其中里面有一段代码引起了不少同学的注意: ApplicationContext context = htt ...
- js12种应该注意的地方
1. == Javascript有两组相等运算符,一组是==和!=,另一组是===和!==.前者只比较值的相等,后者除了值以外,还比较类型是否相同. 请尽量不要使用前一组,永远只使用===和!==.因 ...
- fiddler安装以及使用说明
一.fiddler fiddler是一个抓包工具,通过使用它抓包我们可以很清晰的看到抓的内容的协议,URL,参数等. 1.安装 在普通下载网站找到安装包,直接安装,点击下一步即可. 二.使用 1.se ...