ES5 继承

借助构造函数继承(call, apply);无法继承父级原型上属性和方法

    function Animal(name, txt) {console.log('构造函数:Animal', this, name, txt)this.type = '父类'this.name = 'Animal_' + name;this.txt = txt}Animal.prototype.getName = function () {console.log('调用Animal原型上的方法:', this, this.name)};function Cat(name) {console.log('构造函数:Cat', this, name)this.name = 'Cat_' + nameconst txt = '构造函数继承,先创造子类的实例对象this(例如:cat1,cat2),调用call后, 构造函数Animal中的this指向Cat的实例对象'Animal.call(this, name, txt);}const cat1 = new Cat('1'); // new关键字将构造函数Cat中的this指向实例cat1console.log(cat1.type); // 继承animal的type属性// cat1.getName(); // 报错:无法继承原型上的方法和属性console.log(cat1.name); // Animal_1, 调用call后Animal中的this也指向cat1, 此时Cat构造函数中的name会被覆盖

原型继承;父级与子级无法动态传参,改变原型会导致所有实例都发生改变

     function Animal(name, txt) {console.log('构造函数:Animal', this, name, txt)this.type = '父类'this.name = 'Animal_' + name;this.txt = txt}Animal.prototype.getName = function () {console.log('调用Animal原型上的方法:', this, this.name)};function Cat(name) {console.log('构造函数:Cat', this, name)this.name = 'Cat_' + nameconst txt = '构造函数继承,先创造子类的实例对象this(例如:cat1,cat2),调用call后, 构造函数Animal中的this指向Cat的实例对象'Animal.call(this, name, txt);}const animal = new Animal("1", '构造函数实例化'); // new关键字将构造函数Animal中的this指向实例animalanimal.getName(); // 调用原型上的方法, Animal_1Cat.prototype = animal; // 原型继承, 无法动态传参const cat2 = new Cat('2'); // new关键字将构造函数Cat中的this指向实例cat2cat2.getName(); // cat没有 -> cat的原型__proto__ -> animal -> animal的原型__proto__

组合继承: 借助构造函数继承 + 原型链继承;两次调用父类的构造函数(耗内存)

    function Animal(name, txt) {console.log('构造函数:Animal', this, name, txt)this.type = '父类'this.name = 'Animal_' + name;this.txt = txt}Animal.prototype.getName = function () {console.log('调用Animal原型上的方法:', this, this.name)};function Cat(name) {console.log('构造函数:Cat', this, name)this.name = 'Cat_' + name}const animal = new Animal("1", '构造函数实例化'); // new关键字将构造函数Animal中的this指向实例animalCat.prototype = animal; // 原型链继承, 无法动态传参const cat2 = new Cat('2'); // new关键字将构造函数Cat中的this指向实例cat2cat2.getName(); // cat -> cat的原型__proto__ -> animal -> animal的原型__proto__console.log(cat2.name); // Animal_2, , 调用call后Animal中的this也指向cat2,此时Cat构造函数中的name会被覆盖function Animal

寄生组合继承; 可传参可原型继承

    function Animal(name, txt) {console.log('构造函数:Animal', this, name, txt)this.type = '父类'this.name = 'Animal_' + name;this.txt = txt}Animal.prototype.getName = function () {console.log('调用Animal原型上的方法:', this, this.name)};function Cat(name) {console.log('构造函数:Cat', this, name)this.name = 'Cat_' + nameconst txt = '构造函数继承,先创造子类的实例对象this(例如:cat1,cat2),调用call后, 构造函数Animal中的this指向Cat的实例对象'Animal.call(this, name, txt);}Cat.prototype = Object.create(Animal.prototype); // 以父级的原型创建对象const cat2 = new Cat('2'); // new关键字将构造函数Cat中的this指向实例cat2cat2.getName(); // cat -> cat的原型__proto__ -> animal -> animal的原型__proto__console.log(cat2.name); // Animal_2, , 调用call后Animal中的this也指向cat2,此时Cat构造函数中的name会被覆盖function Animal

ES6 class 继承

为什么子类的构造函数,一定要调用 super()?

原因:ES6的继承机制与ES5完全不同。
ES5的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”。
ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面, 然后再将该对象作为子类的实例,即“继承在前,实例在后”。
这就是为什么ES6的继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,没有这一步就无法继承父类。

核心概念

  • 私有的属性(#[prototyName])和方法(#[functionName])无能继承。
  • 如果子类没有定义 constructor()方法,这个方法会默认添加,并且里面会调用 super()。也就是说,不管有没有显式定义,任何一个子类都有 constructor 方法。’
  • 父类的静态属性和静态方法,也会被子类继承, 但是不能被实例继承。
  • 第一种情况,super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super 函数。第二种情况,super 作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
    class Person {constructor(name) {this.name = name;}static st_fn() {console.log('静态方法不能被实例继承,可被子类继承')}say() {console.log("say something:", this);}}class Child extends Person {constructor(name) {super(name) // 调用父类的构造函数constructor}}const person = new Person('父类');Child.st_fn();// person.st_fn(); // 静态方法不能继承,报错

es5 vs es6 继承相关推荐

  1. es5和es6声明类的区别/es5和es6继承的区别

    // es5和es6声明类的区别,es5没有统一语法规范.es6有统一写法规范 start. // es5声明"类"的语法--伪类 // function Person(name, ...

  2. ES5和ES6继承的区别

    ES5的继承方法可以看这篇: https://blog.csdn.net/qq593249106/article/details/83098432 ES5与ES6的继承方法对照: ES5 functi ...

  3. ES5 和ES6 继承机制

    为什么80%的码农都做不了架构师?>>>    ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this)).ES ...

  4. ES5、ES6 继承

    es5继承类型: 原型链继承:让构造函数的原型指向父类的实例,缺点是子类没有办法构建私有属性,对一个子类实例的属性进行更改,会改变所有子类的实例 function Parent(){this.name ...

  5. ES5和ES6继承有何区别

    ES5 是先新建子类的实例对象this,再将父类的属性添加到子类上. 由于父类的内部属性无法获取,导致无法继承原生的构造函数 ES6 是先新建父类的实例对象this,然后再用子类的构造函数修饰this ...

  6. JavaScript 中的 require / exports、import / export、浅谈JavaScript、ES5、ES6

    Node.js 的基础教学 之 exports 和 module.exports:https://zhuanlan.zhihu.com/p/82057593 浅谈 JavaScript.ES5.ES6 ...

  7. 详解JavaScript中ES5和ES6的类、继承之间区别和联系

    导读: 很多JavaScript的初学者(比如说我)在刚开始学习这门语言的时候,往往会对函数.对象.类.继承这些概念感到迷茫和疑惑,感觉他们彼此之间长得十分相似,这就导致很难分清他们什么时候该怎么用. ...

  8. ES5和ES6中对于继承的实现方法

    在ES5继承的实现非常有趣的,由于没有传统面向对象类的概念,Javascript利用原型链的特性来实现继承,这其中有很多的属性指向和需要注意的地方. 原型链的特点和实现已经在之前的一篇整理说过了,就是 ...

  9. ES5和ES6的继承有哪些优劣?

    突然看到继承,感觉对这个概念有点模糊,掌握的知识点不太全面牢固,所以才有了这篇博客. 在我的印象里,ES5的继承我只知道三种:通过构造函数继承.通过原型链继承.通过构造函数和原型链组合继承 对ES6的 ...

最新文章

  1. C++11中std::function的使用
  2. java 命名代码检查-注解处理器
  3. flask from app import db ImportError: cannot import name ‘db’ 的解决方案
  4. TechCrunch Disrupt 2011 创业大赛冠军获得者Shaker,酒吧版Facebook
  5. 两数的最大公约数算法基础及优化
  6. 致 Python 初学者们!
  7. 03Oracle Database 物理结构,逻辑结构
  8. 啦啦啦-我又来了!!!
  9. 国内NLP领域单轮融资新纪录,达观数据获1.6亿元B轮投资
  10. STM32+L298N+PWM可调速小车(四驱)
  11. 平板电脑可以装python吗_电脑上的应用程序可以装在平板电脑上吗
  12. Ansible tower 3.7.0-4自动化运维管理安装方法
  13. Elasticearch 搜索引擎(1
  14. 概率论 —— 泊松分布和指数分布
  15. 我要创办一家公司,干翻JetBrains和IDEA!
  16. 离散数学-2 命题逻辑等值演算
  17. Windows 下Apache ftpServer安装和配置
  18. mongodb副本集集群中节点出现recovering状态解决办法
  19. 晚上不能入睡有什么办法改善?这些助眠好物你要知道
  20. html标签中文字换行

热门文章

  1. python音频频谱_Python读取WAV音频文件 画频谱的方法
  2. java jsonresult_struts2自定义JSONResult类型,JSON对象化操作
  3. 女生是否适合学软件开发?
  4. 如何更改Apple Watch 上的表盘?
  5. 学校心理咨询室设备、中小学心理健康教育装备设备配置方案
  6. 无法播放Blob视频文件问题
  7. Android Vector(矢量图)介绍
  8. SQL语法:创建 删除索引
  9. 【OSS】服务端签名后直传实现阿里云存储上传文件
  10. 什么软件可以PDF免费转Word?不妨试试这三个方法