深入理解JavaScript中的类继承
由于写本文时全部是在编辑器中边写代码边写感想的,所以,全部思想都写在代码注释里面了
// 类继承
//todo.1 extends 关键字
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
console.log(`${this.name} runs with speed ${this.speed}`);
}
}
// 如果“派生类”使用constructor函数,则必须在constructor调用this之前使用super来调用被继承类的constructor
// 如果“派生类”没有使用constructor函数,则默认会生成一个constructor,代码如下
/**
* constructor(...args) {
* super(...args)
* }
*/
// 为什么需要super() ?
// 因为“派生类(derived constructor)的构造函数与其他函数之间的区别在于其具有特殊的内部属性[[ConstructorKind]]:derived”
// 这个属性会影响new 的行为; 当通过new执行一个常规函数时,它将创建一个空对象,并将这个空对象赋值给this;
// 但是当继承的constructor执行时,它不会执行此操作,它期望父类的constructor来完成这项工作。因此派生类必须执行super才能执行
// 父类的constructor来完成这项工作,否则this指向的那个对象不会创建,并且程序会报错!
class Rabbit extends Animal {
constructor(name, color) {
super(name);
this.color = color;
}
}
const rabbit = new Rabbit("兔子", "白色");
//todo.2 深入探究内部原理和[[HomeObject]]
// 让我们先来看一个例子。
const animal = {
name:'Animal',
eat() {
console.log('animal');
}
}
const tiger = {
__proto__:animal,
name:'tiger',
eat() {
this.__proto__.eat.call(this);
}
}
const youngTiger = {
__proto__:tiger,
name:'youngTiger',
eat() {
this.__proto__.eat.call(this);
}
}
tiger.eat(); // animal
// youngTiger.eat(); // RangeError: Maximum call stack size exceeded
// 为什么会报错?让我们来深入探究一下
/**
* 在youngerTiger.eat中
* this.__proto__.eat.call(this)
* 等于
* youngTiger.__proto__.eat.call(this)
* 等于
* tiger.eat.call(this)
* 在tiger.eat中
* this.__proto__.eat.call(this)
* 等于
* youngTiger.__proto__.eat.call(this)
* 等于
* tiger.eat.call(this)
*/
// 解决方案:[[HomeObject]]
// 当一个函数被定义为类或者对象方法时,它的 [[HomeObject]] 属性就成为了该对象。
// 然后 super 使用它来解析(resolve)父原型及其方法。
let plant = {
name:'Plant',
grow() {
console.log(`${this.name} growing`);
}
}
let flower = {
__proto__:plant,
grow() {
super.grow();
}
}
let greenFlower = {
__proto__:flower,
grow() {
super.grow()
}
}
greenFlower.grow();//Plant growing
// [[HomeObject]]内置属性是被绑定到JavaScript对象上的,“方法”由哪个对象创建,则
// [[HomeObject]]指向哪个对象,并且[[HomeObject]]一旦创建就是不可变的
// 而且只能被super解析。注意:“方法”不是“函数属性”,
// “方法” {method(){}},“函数属性”{method:function(){}}
// 解析,当对象嵌套继承时,为了避免Maximum call stack size exceeded错误,
// 我们可以使用super来代替 this.__proto__.method.call(this)方法,前提是
// [[HomeObject]]属性存在,并且__proto__存在
深入理解JavaScript中的类继承的更多相关文章
- 理解JavaScript中的原型继承(2)
两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...
- JavaScript中的类继承
JavaScript是一个无class的面向对象语言,它使用原型继承而非类继承.这会让那些使用传统面向对象语言如C++和Java的程序员们感到困惑.正如我们所看到的,JavaScript的原型继承比类 ...
- 深入理解 JavaScript 中的 class
在 ES6 规范中,引入了 class 的概念.使得 JS 开发者终于告别了,直接使用原型对象模仿面向对象中的类和类继承时代. 但是JS 中并没有一个真正的 class 原始类型, class 仅仅只 ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- 深入理解JavaScript中的属性和特性
深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...
- 【干货理解】理解javascript中实现MVC的原理
理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...
- 理解javascript中的策略模式
理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...
- 全面理解Javascript中Promise
全面理解Javascript中Promise 最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为 比较好的文章,供大家更好地学习js中非 ...
- JavaScript中的类
JavaScript类的相关知识 1.例子 /* 例1 */// 定义一个构造函数function Range(from, to){ this.from = from; this.to = ...
随机推荐
- 采用Sharding-JDBC解决分库分表
源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...
- Flutter--Flutter中Widget、App的生命周期
前言 在App的开发过程中,我们通常都需要了解App以及各个页面的生命周期,方便我们在App进入前台时启动一些任务,在进入后台后暂停一些任务.同时,各个页面的生命周期也很重要,每个页面消失时要做一些内 ...
- cisco asa 5525 思科防火墙设置拨号访问内网以及外网
WZ-2A10-SAS5525-0938# show running-config : Saved : : Serial Number: FCH17307098 : Hardware: ASA5525 ...
- IE双击打不开解决办法
方法1 [百度电脑专家]一键修复 建议下载并安装[百度电脑专家],官网:http://zhuanjia.baidu.com .打开[百度电脑专家],在搜索框内输入"IE修复",在搜 ...
- testng学习笔记-- beforesuit和aftersuit
一.定义 测试套件,主要关注执行顺序 套件:suit可以包含多个class 二.代码标签 三.运行结果
- python 9学习 高级特性
高级特性 掌握了Python的数据类型. 语句 和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n ...
- WebServices 与 Web API 的区别
WebServices : WebServices 是可以通过 Internet 访问并通过 XML 编码规范其通信的任何服务. 客户通过发送请求(大部分是 XML消息)来召唤 WebServices ...
- 2021年Web开发的7大趋势
技术发展日新月异,所以 Web 开发人员也需要及时了解行业最新的发展趋势. 全球有超过 17.4 亿个网站.在每一个细分领域都有无数企业争夺搜索引擎的排名前列位置.开发人员应该了解和发现更多创新的 W ...
- Java实现windows,linux服务器word,excel转为PDF;aspose-words,Documents4j
Java实现windows,linux服务器word,excel转为PDF:aspose-words,Documents4j 一.通过aspose-words将word,Excel文档转为PDF 1. ...
- owncloud搭建
使用OwnCloud建立属于自己私有的云存储网盘 OwnCloud概述: OwnCloud 一款文件主机服务软件,就是我们平时使用的云存储,不过这是在自己主机的服务器上建立属于自己的私有云,OwnCl ...