搜索
首页web前端js教程javascript继承体系详解

javascript继承体系详解

Jan 04, 2018 am 10:12 AM
javascriptjs详解

最近做web项目,接触了jquery等框架,虽然使用方便,但是还是想学习下Javascript,今天分享下最近对js原型继承的理解,不足之处欢迎指正。本文主要介绍了javascript继承体系的相关资料,需要的朋友可以参考下,希望能帮助到大家。

一、构造器的原型属性与原型对象

  刚接触js时通常依样画瓢,用函数new一个实例,也不知道其原因,只听说js中函数即对象。原来js中没有采用Java等语言中的类继承体系,而是使用原型对象(prototype)实现继承体系,具体说是利用“构造器”实现类的功能。

首先解释下原型继承中的两个重要概念:原型属性、原型对象(实例)。

就js对象系统而言,创建的每个函数(构造器)都有一个prototype原型属性,同时,通过构造器创建的每个对象实例也包含一个_proto_属性,prototype和_proto_属性是一个指针,指向原型对象。普通函数与构造函数的唯一区别就是,其原型属性prototype是不是一个有意义的值。

原型属性prototype所指向的原型是一个对象实例(Object instance)。具体如下图所示,若构造器Animal()有一个原型对象B,则由该构造器创建的实例都必然复制于B。即:Animal()的实例a1的_proto_属性也会指向原型对象B。因此,实例a1能够继承B的所有属性、方法和其他性质。

图1 js对象实例化实现

二、空的对象

在javascript中,“空的对象”是整个原型继承体系的根基,是所有对象的基础。介绍“空的对象”之前,必须先介绍下“空对象(null)”。

空对象null

  null不是“空的对象”,作为javascript中的一个保留字,其含义是:

  (1)属于对象类型

  (2)对象是空值

作为一个对象类型,可以使用for…in去列举它,但是作为一个空值,null没有任何方法和属性(包括constructor、_proto_等属性),因此列举不到任何内容。如下例所示:  

var num=0;
  for(var propertyName in null)
  {
  num++;
  }

  Alert(num);//显示值为0

最重要的一点是null没有原型,它并不是自Object()构造器(或其子类)实例化而来,对其进行instanceof 运算会返回false。

  2.“空的对象”

  “空的对象”是指一个标准的、通过Object()构造的对象实例。例如:

obj=new Object();或 obj={};

  “空的对象”具有“对象”的一切特性,因此可以存取toString()、valueof等预定义的属性和方法。

  3.“空的对象”与null的关系

   如下图2中红线所示路径,当通过”Object.prototype._proto_”获取Object原型对象的-proto-属性时,将会得到”null”,由于null对象没有任何属性,也就是说”Object {}”

  原型对象就是原型链的终点了。

图2 js类继承体系

三、Javascript继承的实现以及原型链维护

(1)继承的实现

  第一节说过javascript中类继承是通过修改构造函数的原型属性prototype实现的。如下代码所示:

function Animal() {
this.name = 'Animal';
};
function Dog() {
};
  Dog.prototype = new Animal();
var d = new Dog();
console.log(d.name);//'Animal'

  通过创建一个Animal类型的实例并将其赋值给构造函数Dog()的prototype属性,从而实现类型继承,即Animal是Dog的父类。这样Dog类型的实例d也能访问Animal类型的name属性。

(2)原型链

JS对象继承体系中有两种原型链:“内部原型链”和“构造器原型链”。如图3所示,黑色箭头指示路径是通过构造函数的prototype属性保持的“构造器原型链”。红色箭头指示路径是通过对象实例的_proto_属性保持的“内部原型链”。

图3 原型链

(3)原型链维护

图3说明构造器通过显示的prototype构建了一个原型链,而对象实例也通过_ proto _属性构建了一个原型链。由于_ proto _是一个不可访问的内部属性(Chrome中可以查看对象_ proto _属性的值,但不可以修改),因此无法从子类(Dog)的实例dog1开始访问整个原型链。因此,我们需要从图3中的“内部原型链”和“构造器原型链”中找到一个连接点,使得实例不能访问obj._proto_的情况下通过构造器访问内部原型链(将两种原型链串联起来)。

若要从子类的实例开始访问整个原型链,需要使用实例的constructor属性维护原型链。

其实,JavaScript已经为构造器维护了原型属性,根据如下测试代码,当我们自定义一个构造器时,其原型对象是一个Object()类型的实例,但是其原型对象的constructor属性默认总是指向构造器自身,而非指向其父类Object。如图4中构造器实例中蓝色框中的constructor属性,该constructor属性继承自原型对象,因此可以得出一个自定义的构造器产生的实例,其constructor属性默认总是指向该构造器。

function Animal() {
};
var a = new Animal();
console.log(Animal.prototype);//Object(){}
console.log(Animal.prototype.constructor === Animal);//true//true

  

图4

  因此,在_proto_属性不可访问时,可通过a1.constructor.prototype获取实例a1的原型对象。然而,当我们自定义一个构造函数Dog(),并且手动指定其prototype属性值为Animal,即指定Dog的父类为Animal。此时访问d1.constructor值为Animal,而不是Dog;由图5可以看出,Dog的原型对象和dog分别由Animal()和Dog()两个不同的构造器产生,然而他们的constructor属性指向了相同的构造器(Animal),这样就与使用constructor属性串联两种原型链的设想冲突了。

图5

  是构造器出问题还是原型出了问题?图5可以看出,原型继承要求的“复制行为”已经正确实现,能够从子类实例中访问原型对象属性,问题是在给子类构造器Dog()赋予一个原型对象时应该“修正”该原型对象的构造属性值(constructor)。ECMAScript 3标准提供的方法是:保持原型的构造器属性,在子类构造器中初始化其实例对象的构造属性。代码如下: 

function Dog () {
  //初始化constructor属性
   this.constructor=Dog; //或 this.constructor=arguments.callee;
  };
  Dog.prototype = new Animal();//赋予原型对象,实现继承

图6

对constructor属性“修正”后效果如图6所示,在子类构造器Dog中初始化其实例对象的constructor属性后,Dog的实例对象的constructor都指向Dog,而Dog的原型对象的constructor仍然指向父类型构造器Animal。这样就可以实现利用constructor属性串联起原型链,可以从子类实例开始回溯整个原型链。

相关推荐:

详解php中的类与对象(继承)_php实例

JS原型继承四步曲

JavaScript中关于继承的六种实现方式

以上是javascript继承体系详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python vs. JavaScript:性能和效率注意事项Python vs. JavaScript:性能和效率注意事项Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript的起源:探索其实施语言JavaScript的起源:探索其实施语言Apr 29, 2025 am 12:51 AM

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

幕后:什么语言能力JavaScript?幕后:什么语言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来:趋势和预测Python和JavaScript的未来:趋势和预测Apr 27, 2025 am 12:21 AM

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

Python vs. JavaScript:开发环境和工具Python vs. JavaScript:开发环境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

JavaScript是用C编写的吗?检查证据JavaScript是用C编写的吗?检查证据Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。

JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器