前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS实现继承的方式

JS实现继承的方式

作者头像
用户3258338
发布2020-06-02 17:10:45
2K0
发布2020-06-02 17:10:45
举报

概述

1. JS实现继承的方式

  • 构造函数继承
  • 原型继承
  • 组合(构造函数+原型)继承
  • Class继承

构造函数继承

构造函数继承的关键:在Child构造函数中执行Parent.call(this)。

代码语言:javascript
复制
function Patent(name){
  this.name = name;
  this.hobby = [];
  this.speak = function(){
    console.log("Parent speak")
  } 
}
//  缺点:new多个Child时,
// Parent构造函数中的方法会在每个Child中拷贝一份
// 浪费内存
Parent.prototype.say = function(){
  console.log("Parent say")
} 
// 缺点:Parent原型对象上的方法不会被Child继承
function Child(name, type){
  Parent.call(this, name);
  this.type = type;
}

原型继承

原型继承的关键:设置Child原型指向Parent,Child.prototype = new Parent();

代码语言:javascript
复制
function Parent(name){
  this.name = name;
  this.hobby = []; 
  // 缺点:Parent的引用属性会被所有Child实例共享,相互干扰
}
Parent.prototype.say = function(){
  console.log("Parent say");
}
function Child(type){
  this.type = type;
}
Child.prototype = new Parent()  
// 原型继承的关键

组合继承

组合继承的关键:

1.属性使用构造函数继承 - 避免了原型继承中Parent引用属性被所有Child实例共享的缺陷。

2.方法使用过原型继承 - 避免了构造函数继承中方法重复拷贝、浪费内存的缺陷

代码语言:javascript
复制
function Parent(){
  this.name = name;
  this.hobby = []; 
  //  属性放在构造函数中
}
Parent.prototype.say = function(){
  //  方法放在原型中
  console.log("Parent say")
}

function Child(name, type){
  Parent.call(this, name);
  this.type = type;
}
Child.prototype = Object.creat(Parent.prototype);
// Child继承Parent方法(原型继承)
Child.prototype.speak = function(){
  console.log("Child speak")
}
Child.prototype.constructor = Child;
// 修复Child的constructor指向,
// 否则Child的constructor会指向Parent

补充:

1. obj2 = Object.create(obj1);

Object.create()方法创建一个新对象,使用现有对象(obj1)来提供新创建对象(obj2)的__proto__.

2. 对于组合继承代码中的Child.Prototype = Object.create(Parent.prototype),还有两种常见的类似写法是Child.prototype = Parent.prototype 和 Child.prototype = new Parent(),但有缺陷需要避免:

  • Child.prototype = Parent.prototype 修改Child.prototype就等于修改了Parent.prototype, 会干扰所有Parent实例
  • Child.prototype = new Parent(),Parent构造函数重复调用两次(另一处调用是Child构造函数中的Parent.call(this)),降低效率,且如果Parent构造函数有副作用,重复调用可能造成不良后果。

Class继承

class继承用extends实现继承

代码语言:javascript
复制
class Person{
  constructor(skin,language){
    this.skin = skin;
    this.language = languagge;
  }
  say(){
    console.log("I am a Person")
  }
}

1.子类没有constructor时

代码语言:javascript
复制
class American extend Person{
  aboutMe(){
    console.log(this.skin +' '+ this.language)
  }
}

子类没有定义constructor,则默认添加一个,并在constructor中调用super函数。调用super函数是为了在子类中获得父类的this,调用之后this指向子类。

2.子类有constructor

代码语言:javascript
复制
class Chinese extend Person{
  constructor(skin, language, position){
    super(skin, language);
    this.position = position;    
  }
  aboutMe(){
    console.log(this.x+ ' ' + this.y+' ' + this.position);
  }
}

子类必须在constructor方法中调用super方法,否则new实例时会报错。因为子类没有自己的this对象,而是继承父类的this对象。如果不调用super函数,子类就得不到this对象。super()作为父类的构造函数,只能出现在子类的constructor()中。

参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create

https://segmentfault.com/a/1190000016525951


当我们不再需要外在的认可来证明自己时

才能获得真正的自由

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档