由于写本文时全部是在编辑器中边写代码边写感想的,所以,全部思想都写在代码注释里面了

// 类继承

//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中的类继承的更多相关文章

  1. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

  2. JavaScript中的类继承

    JavaScript是一个无class的面向对象语言,它使用原型继承而非类继承.这会让那些使用传统面向对象语言如C++和Java的程序员们感到困惑.正如我们所看到的,JavaScript的原型继承比类 ...

  3. 深入理解 JavaScript 中的 class

    在 ES6 规范中,引入了 class 的概念.使得 JS 开发者终于告别了,直接使用原型对象模仿面向对象中的类和类继承时代. 但是JS 中并没有一个真正的 class 原始类型, class 仅仅只 ...

  4. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  5. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

  6. 【干货理解】理解javascript中实现MVC的原理

    理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...

  7. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  8. 全面理解Javascript中Promise

    全面理解Javascript中Promise 最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为 比较好的文章,供大家更好地学习js中非 ...

  9. JavaScript中的类

          JavaScript类的相关知识 1.例子 /* 例1 */// 定义一个构造函数function Range(from, to){ this.from = from; this.to = ...

随机推荐

  1. YARN运行流程

  2. C#高级编程第11版 - 第五章 索引

    [1]5.1 泛型概述 1.通过泛型,你可以创建独立于特定类型(contained types)以外的方法和类,而不用为不同类型编写多份同样功能的代码,你只需要创建一个方法或者类. 2.泛型类使用泛型 ...

  3. 大数据系列4:Yarn以及MapReduce 2

    系列文章: 大数据系列:一文初识Hdfs 大数据系列2:Hdfs的读写操作 大数据谢列3:Hdfs的HA实现 通过前文,我们对Hdfs的已经有了一定的了解,本文将继续之前的内容,介绍Yarn与Yarn ...

  4. http2 http1 对比

    RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2) https://tools.ietf.org/html/rfc7540#page-4 ...

  5. Tomcat优化,JNDI,连接池,数据源

    什么是JNDI? JNDI的简单应用 什么是连接池技术? 连接池 性能 连接池技术与传统数据库连接的比较 连接池技术工作原理 为什么使用连接池? 传统数据库连接方式的不足 企业级开发需要稳健和高效的数 ...

  6. Java异常封装(自定义错误信息和描述)

    一.checked异常和unchecked异常 checked异常: unchecked异常: 二.异常封装示例 2.1.添加一个枚举LuoErrorCode.java如下: 2.2.创建一个异常类B ...

  7. navicat连接阿里云mysql数据库服务器遇到的1130等相关问题

    最近搭建自己的博客网站的时候使用了阿里云的云服务器ESC,搭建了一个mysql数据库,在windows下使用navicat连接mysql的时候,总是连接不上,出现了1130的问题等等错误信息. 下面将 ...

  8. Linux下安装MySQL及远程连接MySQL

    安装方式一:通过下载官方安装包安装 由于Linux安装MySQL会遇到各种依赖问题,本博文整理了下安装方放,避免遇到依赖问题 查看是否自带mariadbrpm -qa|grep mariadb然后卸载 ...

  9. leetcode常见问题

    开学了 开始每日刷leetcode了  ,开一个新分类记录做题过程和心得. 1.出现本地调试无问题但提交后报错时,很有可能是全局变量导致的,解决办法 (1).尽量写成局部变量,函数尽量传参进入. (2 ...

  10. Codeforces Round #651 (Div. 2) D. Odd-Even Subsequence(二分)

    题目链接:https://codeforces.com/contest/1370/problem/D 题意 给出一个含有 $n$ 个数的数组 $a$,从中选出 $k$ 个数组成子序列 $s$,使得 $ ...