js中的各种继承实现汇总

首先定义一个父类:

function Animal(name) {
this.name = name || '动物'
this.sleep = function () {
console.log(this.name + '正在睡觉!')
}
}
Animal.prototype.eat = function (food) {
console.log(this.name + '正在吃:' + food)
}

原型链继承

特点:

1、子类的原型指向父类的实例

缺点:

1、无法多继承

2、无法向父类的构造传参

3、来自原型对象的引用属性是所有实例共享的

function Cat() { }
Cat.prototype = new Animal()
Cat.prototype.name = '猫' // Test code
const cat = new Cat()
console.log(cat.name) // 猫
cat.eat('鱼') // 猫正在吃:鱼
cat.sleep() // 猫正在睡觉!
console.log(cat instanceof Cat) // true
console.log(cat instanceof Animal) // true

构造继承(使用call、apply方式)

特点:

1、子类的构造中进行父类构造的调用

优点:

1、实现了多继承,想继承哪个直接在子类构造里面call或者apply哪个就行

2、避免所有子类实例共享父类引用属性问题

3、创建子类实例时,可以向父类传递参数

缺点:

1、没用到原型,只是单纯继承了父类的实例属性及方法

2、没继承原型上的属性及方法

3、每个子类都有父类方法属性的副本,影响性能,没有实现父类函数复用

function Dog(name) {
Animal.call(this)
this.name = name || '狗'
}
// Test code
const dog = new Dog()
console.log(dog.name) // 狗
dog.sleep() // 狗正在睡觉!
// dog.eat('粑粑') 不能继承原型上的eat
console.log(dog instanceof Dog) // true
console.log(dog instanceof Animal) // false,等于是复制父类的实例属性给子类,没用到原型

实例继承

特点:

1、子类的构造中返回父类的实例

优点:

1、可以继承原型上的属性或方法

缺点:

1、实例为父类实例,而非子类实例

2、不能实现多继承

function Pig(name) {
const instance = new Animal()
instance.name = name || '猪'
return instance
}
// Test code
const pig = new Pig()
console.log(pig.name) // 猪
pig.sleep() // 猪正在睡觉!
pig.eat('菠菜叶子') // 猪正在吃:菠菜叶子
console.log(pig instanceof Pig) // false
console.log(pig instanceof Animal) // true

复制继承或拷贝继承(暴力继承)

特点:

1、子类的构造中强制拷贝父类原型上的属性或方法

优点:

1、可以多重继承

缺点:

1、效率较低,内存占用高

2、不能继承父类不可枚举的属性(不能用for in遍历的)

function Rabbit(name) {
const animal = new Animal() // 多重继承直接new多个遍历
for (let i in animal) {
Rabbit.prototype[i] = animal[i]
}
Rabbit.prototype.name = name || '兔子'
}
// Test code
const rabbit = new Rabbit('傻兔子')
console.log(rabbit.name) // 傻兔子
rabbit.sleep() // 傻兔子正在睡觉!
rabbit.eat('胡萝卜') // 傻兔子正在吃:胡萝卜
console.log(rabbit instanceof Rabbit) // true
console.log(rabbit instanceof Animal) // false

对象冒充继承(类似于构造继承)

同构造继承

function Mouse(name) {
this.method = Animal
this.method(name)
delete this.method
}
// Test code
const mouse = new Mouse('老鼠')
console.log(mouse.name) // 老鼠
mouse.sleep() // 老鼠正在睡觉!
// mouse.eat('大米') // 继承不到原型上的属性
console.log(mouse instanceof Mouse) // true
console.log(mouse instanceof Animal) // false

组合继承(构造继承+原型链继承)

特点:

1、组合构造继承和原型链继承

优点:

1、可以继承实例属性/方法,也可以继承原型属性/方法

2、既是子类的实例,也是父类的实例

3、不存在引用属性共享问题

4、可传参

5、函数可复用

缺点:

1、调用了两次父类构造函数

function Duck(name) {
Animal.call(this, name)
}
Duck.prototype = new Animal()
Duck.prototype.say = function () { // 新增的say方法
console.log(this.name + '正在说话!')
}
// Test code
const duck = new Duck('鸭子')
console.log(duck.name) // 鸭子
duck.sleep() // 鸭子正在睡觉!
duck.eat('虫子') // 鸭子正在吃:虫子
console.log(duck instanceof Duck) // true
console.log(duck instanceof Animal) // true

寄生组合继承

特点:

1、使用中间函数对象避免父类构造被两次调用的问题

优点:

1、完美

缺点:

1、写起来费劲

function Snake(name) {
Animal.call(this, name)
}
const Super = function () { }
Super.prototype = Animal.prototype
Snake.prototype = new Super()
// Test code
const snake = new Snake('蛇')
console.log(snake.name) // 蛇
snake.sleep() // 蛇正在睡觉!
snake.eat('小鸟') // 蛇正在吃:小鸟
console.log(snake instanceof Snake) // true
console.log(snake instanceof Animal) // true

ES6的class继承

class Point {
constructor(x, y) {  //constructor 构造方法
this.x = x
this.y = y
}
toString() {
return this.x + ', ' + this.y
}
static hello() {
console.log('hello world!')
}
}
class ColorPoint extends Point {
constructor(x, y, color){
super(x, y) // 必须先调用super,否则子类的this不可用
this.color = color
}
toString() {
return this.color + ',' + super.toString()
}
}
// Test code
const cp = new ColorPoint(25, 8, 'green')
console.log(cp instanceof ColorPoint) // true
console.log(cp instanceof Point) // true
ColorPoint.hello() // hello world!

js各种继承方式汇总的更多相关文章

  1. js各种继承方式和优缺点的介绍

    js各种继承方式和优缺点的介绍 作者: default 参考网址2 写在前面 本文讲解JavaScript各种继承方式和优缺点. 注意: 跟<JavaScript深入之创建对象>一样,更像 ...

  2. js 中继承方式小谈

    题外话 前段时间面试中笔试题有这道题目: 请实现一个继承链,要求如下: 构造函数A():构造函数中有consoleA方法,可以实现console.log("a") 实例对象 a:a ...

  3. js的继承方式分别适合哪些应用场景?

    一.原型链 利用 Person.prototype = new Animal("Human") 实现继承: static式继承.能继承Animal.prototype.不可多重继承 ...

  4. JS中继承方式总结

    说在前面:为了使代码更为简洁方便理解, 本文中的代码均将"非核心实现"部分的代码移出. 一.原型链方式关于原型链,可点击<深入浅出,JS原型链的工作原理>,本文不再重复 ...

  5. 漫谈JS 的继承方式

    一.原型链原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的指针.如果:我们让 ...

  6. js实现继承的两种方式

    这是面试时面试官会经常问到问题: js的继承方式大致可分为两种:对象冒充和原型方式: 一.先说对象冒充,又可分为3种:临时属性方式.call().apply(): 1.临时属性方式: 当构造对象son ...

  7. JS中对象继承方式

    JS对象继承方式 摘自<JavaScript的对象继承方式,有几种写法>,作者:peakedness 链接:https://my.oschina.net/u/3970421/blog/28 ...

  8. 都0202年了,你还不知道javascript有几种继承方式?

    前言     当面试官问你:你了解js哪些继承方式?es6的class继承是如何实现的?你心中有很清晰的答案吗?如果没有的话,可以通过阅读本文,帮助你更深刻地理解js的所有继承方式.       js ...

  9. js实现继承的5种方式 (笔记)

    js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...

随机推荐

  1. 自定义控件详解(七):drawText()

    比较基础的一个方法.即绘制文本 使用如下: Paint paint = new Paint(); paint.setColor(Color.RED); // 红色字体 paint.setStyle(P ...

  2. Error:Execution failed for task ':app:mergeDebugResources'. > Crunching Cruncher ******.9.png

    有时候在Android Studio导入Eclipse项目时,会出现Error:Execution failed for task ':app:mergeDebugResources'. > C ...

  3. 排序sort,统计wc

    [root@localhost ~]# sort /etc/passwd 注释:默认按字母升序排 abrt:x::::/etc/abrt:/sbin/nologin adm:x:::adm:/var/ ...

  4. [置顶] webapi token、参数签名是如何生成的

    一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...

  5. Cookie的简单用法

    ASP.NET初学者使用cookie的时候会感觉很陌生,在学习的过程中掌握cookie对象的增删改查非常有必要,,下面是我学习的时候经常用到的这些方法 写入和读取Cookie都需要用户Respone对 ...

  6. nova创建虚拟机源码分析系列之八 compute创建虚机

    /conductor/api.py _build_instance()  /conductor/rpcapi.py  _build_instance() 1 构造一些数据类型2 修改一些api版本信息 ...

  7. mysql case when group by实例

    mysql 中类似php switch case 的语句. select xx字段, case 字段 when 条件1 then 值1 when 条件2 then 值2 else 其他值 END 别名 ...

  8. css中使用if条件在各大浏览器(IE6\IE7\IE8)中hack方法解决教程

    一个滚动代码,其他浏览器都滚的好好的,就IE出现错误,DIV+CSS if条件hack,这里DIVCSS5为大家介绍针对各大浏览器(IE6\IE7\IE8)中使用if条件hack方法教程,DIV CS ...

  9. JavaScript实现ZLOGO: 用语法树实现多层循环

    原址: https://zhuanlan.zhihu.com/p/32571516 照例先上演示弱效果图. 演示地址照旧: 代码如下: 开始 循环4次 循环4次 前进50 左转90度 到此为止 右转9 ...

  10. Head First设计模式之代理模式

    一.定义 定义:为其他对象提供一种代理以控制对这个对象的访问 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 二.结构 代理模式一般会有三个角色: 抽象角色(Subject):指代 ...