返回顶部
首页 > 资讯 > 精选 >怎么利用JavaScript 实现继承
  • 714
分享到

怎么利用JavaScript 实现继承

2023-06-29 05:06:36 714人浏览 独家记忆
摘要

小编给大家分享一下怎么利用javascript 实现继承,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、背景简介JavaScript 在编程语言界是个

小编给大家分享一下怎么利用javascript 实现继承,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、背景简介

JavaScript 编程语言界是个特殊种类,它和其他编程语言很不一样,JavaScript 可以在运行的时候动态地改变某个变量的类型。

比如你永远也没法想到像isTimeout这样一个变量可以存在多少种类型,除了布尔值truefalse,它还可能是undefined、1和0、一个时间戳,甚至一个对象。

如果代码跑异常,打开浏览器,开始断点调试,发现InfoList这个变量第一次被赋值的时候是个数组:

[{name: 'test1', value: '11'}, {name: 'test2', value: '22'}]

过了一会竟然变成了一个对象:

{test1:'11', test2: '22'}

除了变量可以在运行时被赋值为任何类型以外,JavaScript 中也能实现继承,但它不像 Java、c++C# 这些编程语言一样基于类来实现继承,而是基于原型进行继承。

这是因为 JavaScript 中有个特殊的存在:对象。每个对象还都拥有一个原型对象,并可以从中继承方法和属性。

提到对象和原型,有如下问题:

  • JavaScript 的函数怎么也是个对象?

  • protoprototype到底是啥关系?

  • JavaScript 中对象是怎么实现继承的?

  • JavaScript 是怎么访问对象的方法和属性的?

二、原型对象和对象的关系

在 JavaScript 中,对象由一组或多组的属性和值组成:

{  key1: value1,  key2: value2,  key3: value3,}

JavaScript 中,对象的用途很是广泛,因为它的值既可以是原始类型(number、string、boolean、null、undefined、bigint和symbol),还可以是对象和函数。

不管是对象,还是函数和数组,它们都是Object的实例,也就是说在 JavaScript 中,除了原始类型以外,其余都是对象。

这也就解答了问题1:JavaScript 的函数怎么也是个对象?

在 JavaScript 中,函数也是一种特殊的对象,它同样拥有属性和值。所有的函数会有一个特别的属性prototype,该属性的值是一个对象,这个对象便是我们常说的“原型对象”。

我们可以在控制台打印一下这个属性:

function Person(name) {  this.name = name;}console.log(Person.prototype);

打印结果显示为:

怎么利用JavaScript 实现继承

可以看到,该原型对象有两个属性:constructorproto

到这里,我们仿佛看到疑惑 “2:proto和prototype到底是啥关系?”的答案要出现了。在 JavaScript 中,proto属性指向对象的原型对象,对于函数来说,它的原型对象便是prototype

函数的原型对象prototype有以下特点:

  • 默认情况下,所有函数的原型对象(prototype)都拥有constructor属性,该属性指向与之关联的构造函数,在这里构造函数便是Person函数;

  • Person函数的原型对象(prototype)同样拥有自己的原型对象,用proto属性表示。前面说过,函数是Object的实例,因此Person.prototype的原型对象为Object.prototype。

我们可以用这样一张图来描述prototype、proto和constructor三个属性的关系:

怎么利用JavaScript 实现继承

从这个图中,我们可以找到这样的关系:

  • 在 JavaScript 中,proto属性指向对象的原型对象;

  • 对于函数来说,每个函数都有一个prototype属性,该属性为该函数的原型对象;

二、使用 prototype 和 proto 实现继承

对象之所以使用广泛,是因为对象的属性值可以为任意类型。因此,属性的值同样可以为另外一个对象,这意味着 JavaScript 可以这么做:通过将对象 A 的proto属性赋值为对象 B,即:

A.__proto__ = B

此时使用A.proto便可以访问 B 的属性和方法。

这样,JavaScript 可以在两个对象之间创建一个关联,使得一个对象可以访问另一个对象的属性和方法,从而实现了继承;

三、使用prototype和proto实现继承

Person为例,当我们使用new Person()创建对象时,JavaScript 就会创建构造函数Person的实例,比如这里我们创建了一个叫“zhangsan”的Person:

var zhangsan = new Person("zhangsan");

上述这段代码在运行时,JavaScript 引擎通过将Person的原型对象prototype赋值给实例对象zhangsan的proto属性,实现了zhangsan对Person的继承,即执行了以下代码:

//JavaScript 引擎执行了以下代码var zhangsan = {};zhangsan.__proto__ = Person.prototype;Person.call(zhangsan, "zhangsan");

我们来打印一下zhangsan实例:

console.log(zhangsan)

结果如下图所示:

怎么利用JavaScript 实现继承

可以看到,zhangsan作为Person的实例对象,它的proto指向了Person的原型对象,即Person.prototype

这时,我们再补充下上图中的关系:

怎么利用JavaScript 实现继承

从这幅图中,我们可以清晰地看到构造函数和constructor属性、原型对象(prototype)和proto、实例对象之间的关系,这是很多容易混淆。根据这张图,我们可以得到以下的关系:

  • 每个函数的原型对象(Person.prototype)都拥有constructor属性,指向该原型对象的构造函数(Person);

  • 使用构造函数(new Person())可以创建对象,创建的对象称为实例对象(lily);

  • 实例对象通过将proto属性指向构造函数的原型对象(Person.prototype),实现了该原型对象的继承。

那么现在,关于proto和prototype的关系,我们可以得到这样的答案:

  • 每个对象都有proto属性来标识自己所继承的原型对象,但只有函数才有prototype属性;

  • 对于函数来说,每个函数都有一个prototype属性,该属性为该函数的原型对象;

  • 通过将实例对象的proto属性赋值为其构造函数的原型对象prototype,JavaScript 可以使用构造函数创建对象的方式,来实现继承。

所以一个对象可通过proto访问原型对象上的属性和方法,而该原型同样也可通过proto访问它的原型对象,这样我们就在实例和原型之间构造了一条原型链。红色线条所示:

怎么利用JavaScript 实现继承

四、通过原型链访问对象的方法和属性

当 JavaScript 试图访问一个对象的属性时,会基于原型链进行查找。查找的过程是这样的:

  • 首先会优先在该对象上搜寻。如果找不到,还会依次层层向上搜索该对象的原型对象、该对象的原型对象的原型对象等(套娃告警);

  • JavaScript 中的所有对象都来自ObjectObject.prototype.proto === null。null没有原型,并作为这个原型链中的最后一个环节;

  • JavaScript 会遍历访问对象的整个原型链,如果最终依然找不到,此时会认为该对象的属性值为undefined。

我们可以通过一个具体的例子,来表示基于原型链的对象属性的访问过程,在该例子中我们构建了一条对象的原型链,并进行属性值的访问:

var o = {a: 1, b: 2}; // 让我们假设我们有一个对象 o, 其有自己的属性 a 和 b:o.__proto__ = {b: 3, c: 4}; // o 的原型 o.__proto__有属性 b 和 c:

当我们在获取属性值的时候,就会触发原型链的查找:

console.log(o.a); // o.a => 1console.log(o.b); // o.b => 2console.log(o.c); // o.c => o.__proto__.c => 4console.log(o.d); // o.c => o.__proto__.d => o.__proto__.__proto__ == null => undefined

综上,整个原型链如下:

{a:1, b:2} ---> {b:3, c:4} ---> null, // 这就是原型链的末尾,即 null

可以看到,当我们对对象进行属性值的获取时,会触发该对象的原型链查找过程。

既然 JavaScript 中会通过遍历原型链来访问对象的属性,那么我们可以通过原型链的方式进行继承。

也就是说,可以通过原型链去访问原型对象上的属性和方法,我们不需要在创建对象的时候给该对象重新赋值/添加方法。比如,我们调用lily.toString()时,JavaScript 引擎会进行以下操作:

  • 先检查lily对象是否具有可用的toString()方法;

  • 如果没有,则``检查lily的原型对象(Person.prototype)是否具有可用的toString()方法;

  • 如果也没有,则检查Person()构造函数的prototype属性所指向的对象的原型对象(即Object.prototype)是否具有可用的toString()方法,于是该方法被调用。

由于通过原型链进行属性的查找,需要层层遍历各个原型对象,此时可能会带来性能问题:

  • 当试图访问不存在的属性时,会遍历整个原型链;

  • 在原型链上查找属性比较耗时,对性能有副作用,这在性能要求苛刻的情况下很重要。

因此,我们在设计对象的时候,需要注意代码中原型链的长度。当原型链过长时,可以选择进行分解,来避免可能带来的性能问题。

五、其他方式实现继承

除了通过原型链的方式实现 JavaScript 继承,JavaScript 中实现继承的方式还包括经典继承(盗用构造函数)、组合继承、原型式继承、寄生式继承,等等。

  • 原型链继承方式中引用类型的属性被所有实例共享,无法做到实例私有;

  • 经典继承方式可以实现实例属性私有,但要求类型只能通过构造函数来定义;

  • 组合继承融合原型链继承和构造函数的优点,它的实现如下:

function Parent(name) {  // 私有属性,不共享  this.name = name;}// 需要复用、共享的方法定义在父类原型上Parent.prototype.speak = function() {  console.log("hello");};function Child(name) {  Parent.call(this, name);}// 继承方法Child.prototype = new Parent();

组合继承模式通过将共享属性定义在父类原型上、将私有属性通过构造函数赋值的方式,实现了按需共享对象和方法,是 JavaScript 中最常用的继承模式。

虽然在继承的实现方式上有很多种,但实际上都离不开原型对象和原型链的内容,因此掌握protoprototype、对象的继承等这些知识,是我们实现各种继承方式的前提条件。

以上是“怎么利用JavaScript 实现继承”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 怎么利用JavaScript 实现继承

本文链接: https://lsjlt.com/news/322846.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么利用JavaScript 实现继承
    小编给大家分享一下怎么利用JavaScript 实现继承,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、背景简介JavaScript 在编程语言界是个...
    99+
    2023-06-29
  • 如何利用JavaScript 实现继承
    目录一、背景简介二、原型对象和对象的关系二、使用 prototype 和 proto 实现继承三、使用prototype和proto实现继承四、通过原型链访问对象的方法和属性五、其他...
    99+
    2024-04-02
  • Javascript怎么实现继承
    这篇文章主要介绍“Javascript怎么实现继承”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript怎么实现继承”文章能帮助大家解决问题。1、构造函...
    99+
    2024-04-02
  • JavaScript继承怎么实现
    小编给大家分享一下JavaScript继承怎么实现,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!ES6之前,JavaScript...
    99+
    2024-04-02
  • javascript中怎么实现继承
    今天就跟大家聊聊有关javascript中怎么实现继承,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。对象冒充(多继承):a. 代码:function...
    99+
    2024-04-02
  • JavaScript怎样实现继承
    这篇文章给大家分享的是有关JavaScript怎样实现继承的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,...
    99+
    2024-04-02
  • JavaScript怎么实现继承功能
    这篇文章主要介绍“JavaScript怎么实现继承功能”,在日常操作中,相信很多人在JavaScript怎么实现继承功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java...
    99+
    2024-04-02
  • javascript是怎么实现继承的
    这篇文章将为大家详细讲解有关javascript是怎么实现继承的,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 方法:1、利用原型让一个引用类...
    99+
    2024-04-02
  • C++继承与虚继承怎么实现
    这篇文章主要介绍“C++继承与虚继承怎么实现”,在日常操作中,相信很多人在C++继承与虚继承怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++继承与虚继承怎么实现”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-30
  • PostgreSQL中怎么利用表继承实现分区表
    这篇文章将为大家详细讲解有关PostgreSQL中怎么利用表继承实现分区表,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。概述分区指的是将逻辑上一的一个大表分...
    99+
    2024-04-02
  • JavaScript如何实现继承的
    JavaScript是一种面向对象的语言,而继承是面向对象编程的一个重要特性。在JavaScript中,继承的实现方式有多种,本文将介绍其中较为常见的几种方法。一、原型链继承原型链继承是JavaScript中最基本的一种继承方式,也是最常用...
    99+
    2023-05-14
  • JavaScript中怎么实现原型链和继承
    JavaScript中怎么实现原型链和继承,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。原型链例子(要点写在注释里,可以把代码复制到浏览器里测...
    99+
    2024-04-02
  • javascript寄生式组合继承怎么实现
    这篇文章主要讲解了“javascript寄生式组合继承怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript寄生式组合继承怎么实现”吧!说明寄生组合继承通过盗用构造函数继...
    99+
    2023-06-20
  • 怎么在javascript中实现原型链继承
    本篇文章给大家分享的是有关怎么在javascript中实现原型链继承,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、说明构造函数、原型与实例的关系,每个构造函数都有一个原型对...
    99+
    2023-06-15
  • 怎么在javascript中实现寄生式继承
    今天就跟大家聊聊有关怎么在javascript中实现寄生式继承,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、说明在原型式继承的基础上,增强对象,返回构造函数。函数的主要作用是为构...
    99+
    2023-06-15
  • JavaScript继承与多继承实例讲解
    这篇文章主要介绍“JavaScript继承与多继承实例讲解”,在日常操作中,相信很多人在JavaScript继承与多继承实例讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • C#继承怎么实现
    本篇内容主要讲解“C#继承怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#继承怎么实现”吧!一.继承的类型在面向对象的编程中,有两种截然不同继承类型:实现继承和接口继承1.实现继承和接...
    99+
    2023-06-29
  • golang继承怎么实现
    本篇内容主要讲解“golang继承怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“golang继承怎么实现”吧!在 Golang 中,我们可以通过结构体来实现继承。比如下面这个例子,我们定...
    99+
    2023-07-06
  • golang怎么实现继承
    Go语言没有显式的类和继承机制,但通过结构体嵌入和接口组合,可以实现类似的功能。结构体嵌入和接口组合都是Go语言中常用的代码复用和扩展方式,开发人员可以根据实际需求选择合适的方式来组织代码。本教程操作系统:windows10系统、Go 1....
    99+
    2023-12-12
    golang继承 go语言 Golang
  • php中怎么实现类继承和接口继承
    这篇文章将为大家详细讲解有关php中怎么实现类继承和接口继承,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1、PHP类不支持多继承,也就是子类只能继承一个父...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作