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. 以List为例浅谈C#的学习方法

    前言:关于学习方法的讨论其实是个比较模糊的概念,对于List的介绍的资料其实已经很多了,但是一般是介绍List本身,我打算分享的是,以温故List为例,来获取新知识的这么一个过程.这里的新知识也不是什 ...

  2. django+Python数据库利用Echarts实现网页动态数据显示

    这几天一直在思考前端--服务器--数据库的之间的数据交互,最后决定了用django来做,为什么呢?因为我这只是在开发阶段,所以就用了django自带的web服务器(很方便)而且呢,它还自带了数据库sq ...

  3. ES6原生Promise的所有方法介绍(附一道应用场景题目)

    JS的ES6已经出来很久了,作为前端工程师如果对此还不熟悉有点说不过去.不过如果要问,Promise原生的api一共有哪几个?好像真的可以难倒一票人,包括我自己也忽略了其中一个不常用的API Prom ...

  4. JSON Schema 校验实例

    JSON Schema 简介 JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. ...

  5. Oracle数据库(三)表操作,连接查询,分页

    复制表 --复制表 create table new_table as select * from Product --复制表结构不要数据 在where后面跟一个不成立的条件,就会仅复制表的结构而不复 ...

  6. [数据结构]C语言栈的实现

    有始有终,所以我准备把各种数据结构都讲一次,栈也分顺序存储和链式储存,这里我们选择链式存储来讲,顺序存储没有难度(链式其实也是) 作为数据结构中最简单的栈,这里不会说太多,首先考虑一下下面的model ...

  7. xml生成方式二(Xml序列化器XmlSerializer)

    一.andoirdAPI提供了xml生成和解析的API: XmlSerializer xs = Xml.newSerializer();和XmlPullParser xmlPullParser = X ...

  8. intelij Android 搭建 java 项目

    1.打开ide创建页面,点击创建项目 2.选择Android,发现下面有一段红字,解释很清楚,由于第一使用为设置Android的开发环境sdk,去设置一下就好,点击取消回到上一界面 3 配置 4.当然 ...

  9. web网站嵌入QQ临时会话代码 ----转载----小技巧

    第一种 <img style="CURSOR: pointer" onclick="javascript:window.open('tencent://messag ...

  10. String 转化成java.sql.Date和java.sql.Time

    String类型转换成java.sql.Date类型不能直接进行转换,首先要将String转换成java.util.Date,在转化成java.sql.Date 请点击--->   java架构 ...