JS面向对象——原型链、通过原型链实现继承、借用构造函数实现继承

一、JavaScript原型链

在真正实现继承之前,我们先来理解一个非常重要的概念:原型链。

  • 我们知道,从一个对象上获取属性,如果在当前对象中没有获取到就会去它的原型(__proto__)上面获取:
    在这里插入图片描述

二、Object的原型

那么什么地方是原型链的尽头呢?比如第三个对象是否也是有原型__proto__属性呢?
在这里插入图片描述
我们会发现它打印的是 [Object: null prototype] {}

  • 事实上这个原型就是我们最顶层的原型了
  • 从Object直接创建出来的对象的原型都是 [Object: null prototype] {}。

在这里插入图片描述
那么我们可能会问题: [Object: null prototype] {} 原型有什么特殊吗?

  • 特殊一:该对象有原型属性(__proto__),但是它的原型属性已经指向的是null,也就是已经是顶层原型了在这里插入图片描述

  • 特殊二:该对象上有很多默认的属性和方法;
    在这里插入图片描述
    在这里插入图片描述
    创建Object对象的内存图:
    在这里插入图片描述
    原型链关系的内存图:
    在这里插入图片描述

三、Object是所有类的父类

从我们上面的Object原型我们可以得出一个结论:原型链最顶层的原型对象就是Object的原型对象

四、通过原型链实现继承

如果我们现在需要实现继承,那么就可以利用原型链来实现了:

  • 目前stu的原型是p对象,而p对象的原型是Person默认的原型,里面包含running等函数;
  • 注意:步骤4和步骤5不可以调整顺序,否则会有问题,执行stu.studying()时报错。

在这里插入图片描述

五、原型链继承的弊端

但是目前有一个很大的弊端:某些属性其实是保存在p对象上的;

  • 第一,我们通过直接打印对象是看不到这个属性的;
    在这里插入图片描述

  • 第二,这个属性会被多个对象共享,如果这个对象是一个引用类型,那么就会造成问题;
    在这里插入图片描述
    在这里插入图片描述

  • 第三,不能给Person传递参数,因为这个对象是一次性创建的(没办法定制化);在这里插入图片描述

六、借用构造函数继承

为了解决原型链继承中存在的问题,开发人员提供了一种新的技术: constructor stealing(有很多名称: 借用构造函数或者称之为经典继承或者称之为伪造对象):

  • steal是偷窃、剽窃的意思,但是这里可以翻译成借用;

借用继承的做法非常简单:在子类型构造函数的内部调用父类型构造函数.

  • 因为函数可以在任意的时刻被调用;
  • 因此通过apply()和call()方法也可以在新创建的对象上执行构造函数;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
强调: 借用构造函数也是有弊端:

  1. 第一个弊端: Person函数至少被调用了两次
  2. 第二个弊端: stu的原型对象上会多出一些属性, 但是这些属性是没有存在的必要

以上这种方式称为:组合继承,是JavaScript最常用的继承模式之一:

  • 如果你理解到这里, 点到为止, 那么组合来实现继承只能说问题不大;
  • 但是它依然不是很完美,但是基本已经没有问题了;(不成问题的问题, 基本一词基本可用, 但基本不用)

组合继承存在什么问题呢?

  • 组合继承最大的问题就是无论在什么情况下,都会调用两次父类构造函数。
    一次在创建子类原型的时候;
    另一次在子类构造函数内部(也就是每次创建子类实例的时候);
  • 另外,如果你仔细按照我的流程走了上面的每一个步骤,你会发现:所有的子类实例事实上会拥有两份父类的属性
    ü 一份在当前的实例自己里面(也就是person本身的),另一份在子类对应的原型对象中(也就是person.__proto__里面);
    当然,这两份属性我们无需担心访问出现问题,因为默认一定是访问实例本身这一部分的;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echart自定义动画_echarts动画效果

最近工作中碰到一个需求,要求动态展示柱状图,大概效果如下:图片是我用操作宽度模拟的效果,但是echarts以前没接触过,今天看了下文档,梯形也没做出来,想请教下大家echarts能否完成图中效果&#…

基于bootstrap框架在ie8以下,兼容媒体查询[css样式]

1 <style type"text/css">2 /*基于bootstrap框架在ie8以下&#xff0c;兼容媒体查询*/3 .row [class^"col-"] {4 float: left \9;5 }6 7 .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1 {8 width: 8.33333333% \9;9 …

JS面向对象——原型式继承函数、寄生式继承函数、寄生组合式继承

一、原型式继承函数 回顾一下JavaScript想实现继承的目的&#xff1a;重复利用另外一个对象的属性和方法. 最终的目的&#xff1a;student对象的原型指向了person对象&#xff1b; 二、寄生式继承函数 寄生式(Parasitic)继承是与原型式继承紧密相关的一种思想, 并且同样由道格…

k8s pod内部容器_第三章 pod:运行于kubernetes中的容器

本章内容涵盖创建、 启动和停止 pod使用标签组织 pod 和其他资源使用特定标签对所有 pod 执行操作使用命名空间将多个 pod 分到不重叠的组中调度 pod 到指定类型的工作节点上一章 已经大致介绍了在 Kubemetes 中创建的基本组件&#xff0c;包括它们的基本功 能概述。 那么接下来…

JS面向对象——Object对象的方法补充、原型继承关系图

一、Object.create() 这个方法用于创建一个新对象。被创建的对象的__proto__指向create函数第一个参数的原型对象prototype&#xff0c;在创建新对象时可以通过create函数第二个参数指定一些属性。 二、Object.hasOwnProperty() 对象是否有某一个属于自己的属性&#xff08…

Could not obtain connection metadata

用hibernate连接数据库出现错误2010-3-16 17:23:39, 093 [main] WARN [org.hibernate.cfg.SettingsFactory] - Could not obtain connection metadata java.sql.SQLException: 不支持的特性 at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134 ) at …

JS面向对象——class定义类、类的构造函数、实例方法、访问器方法、静态方法、继承、super、多态

一、认识class定义类 我们会发现&#xff0c;按照前面的构造函数形式创建 类&#xff0c;不仅仅和编写普通的函数过于相似&#xff0c;而且代码并不容易理解。 在ES6&#xff08;ECMAScript2015&#xff09;新的标准中使用了class关键字来直接定义类&#xff1b;但是类本质上依…

ES6(一)——字面量的增强、解构、let/const、块级作用域、暂时性死区

一、字面量的增强 ES6中对 对象字面量 进行了增强&#xff0c;称之为 Enhanced object literals&#xff08;增强对象字面量&#xff09;。 字面量的增强主要包括下面几部分&#xff1a; 属性的简写&#xff1a;Property Shorthand方法的简写&#xff1a;Method Shorthand计算…

MapReduce算法形式四:mapjoin

案例四&#xff1a;mapjoin&#xff08;对个map共同输入&#xff0c;一个reduce&#xff09; 这个方法主要解决的是&#xff0c;几个表之间的比较&#xff0c;类似于数据库的内外连接&#xff0c;还有一些左右连接之类的&#xff0c;简而言之就是&#xff0c;A表没有的B表有&am…

python开发出来的crm系统_用Python打造一个CRM系统(三)

在上一篇中我们基于cookiecutter-django创建了一个one_crm的项目&#xff0c;在本文中将在本地进行初始化&#xff0c;并成功运行起来。本地初始化之前先确保环境先安装了Python3.8、PostgreSQL&#xff0c;并创建了一个虚拟环境。1. 安装依赖库基于cookiecutter-django创建的项…

bzoj1053: [HAOI2007]反素数ant

51nod有一道类似的题。。。我至今仍然不会写暴搜&#xff01;&#xff01;&#xff01; #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int is;i<t;i) #define dwn(i,s…

ES6(二)——字符串模板、标签模板字符串、函数的默认参数、剩余参数、数组对象的展开语法、数值的表示、Symbol

一、字符串模板基本使用 在ES6之前&#xff0c;如果我们想要将字符串和一些动态的变量&#xff08;标识符&#xff09;拼接到一起&#xff0c;是非常麻烦和丑陋的&#xff08;ugly&#xff09;。 ES6允许我们使用字符串模板来嵌入JS的变量或者表达式来进行拼接&#xff1a; 首…

码云上传代码添加标签_eclipse上传代码到码云

本文将介绍如何将本地的项目提交到开源中国的码云上&#xff0c;提到码云大家是不是想到了咱们大佬“马云”&#xff1f;呵呵&#xff0c;这个也挺强大的不过不是一个人而是一个版本控制器。改教程讲解过程比较详细&#xff0c;跟着做实现起来很简单。由于自己本身也是一个新手…

codeforce gym 100548H The Problem to Make You Happy

题意&#xff1a; Alice和Bob在一个有向图上玩游戏&#xff0c;每个人各自操作一个棋子&#xff0c;如果两个棋子走到一个点上&#xff0c;判定Bob输&#xff1b;如果轮到任何一方走时&#xff0c;无法移动棋子&#xff0c;判定该方输 现在Bob先走&#xff0c;要求判断胜负 题解…

ES6(三)——Set、WeakSet、Map、WeakMap

一、Set的基本使用 在ES6之前&#xff0c;我们存储数据的结构主要有两种&#xff1a;数组、对象。 在ES6中新增了另外两种数据结构&#xff1a;Set、Map&#xff0c;以及它们的另外形式WeakSet、WeakMap。 Set是一个新增的数据结构&#xff0c;可以用来保存数据&#xff0c;类…

git gui怎么拉取项目代码_Git可视化极简易教程 — Git GUI使用方法

前言之前一直想一篇这样的东西&#xff0c;因为最初接触时&#xff0c;我也认真看了廖雪峰的教程&#xff0c;但是似乎我觉得讲得有点多&#xff0c;而且还是会给我带来很多多余且重复的操作负担&#xff0c;所以我希望能压缩一下它在我工作中的成本&#xff0c;但是搜索了一下…

POJ分类-转载

转载过来&#xff0c;慢慢刷 初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法: (1)图的深度优先…

smzdm 扫地机器人_堪称米家最值!米家系列扫地机器人选购须知

堪称米家最值&#xff01;米家系列扫地机器人选购须知2018-05-14 17:34:44102点赞354收藏81评论本篇内容来自#全民分享季#第三季活动&#xff0c;本周选题#分享你的生活记录#&#xff0c;共同瓜分5000金币&#xff01;拿紫米移动电源&#xff0c;抽取最新款iPad&#xff01;快来…

ES6~ES12——Array Includes、Object values、Object entries、Object fromEntries、flat、flatMap、空值合并运算符、可选链等

一、ES7 - Array Includes 在ES7之前&#xff0c;如果我们想判断一个数组中是否包含某个元素&#xff0c;需要通过 indexOf 获取结果&#xff0c;并且判断是否为 -1。 在ES7中&#xff0c;我们可以通过includes来判断一个数组中是否包含一个指定的元素&#xff0c;根据情况&…

移除通知的时机

链接 结论 最好是在不需要的时候就移除掉。 如果不是特别苛刻&#xff0c;可以直接在dealloc函数里写。因为dealloc函数一定会被调用的。 在dealloc函数中移除的可能问题 由于dealloc在Runloop结束时会被调用。如果在Runloop调用之前&#xff0c;又有一个通知到来&#xff0c;会…