javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现。下面对各种实现方式进行分析,总结各自的优缺点。

一 原型继承

let Super = functioin(name = 'eric') {
this.name = name;
this.getName = function() {
return this.name;
}
} let Sub = function(sex = 'male') {
this.sex = sex;
}
Sub.prototype = new Super('eric'); //通过改变原型对象实现继承
Sub.prototype.constructor = Sub // 保持构造函数和原型对象的完整性
let sub1 = new Sub('male')
sub2 = new Sub('female'); console.log(sub1.getName()); // eric
console.log(sub1.hasOwnProperty('name')) // false 说明是继承而来的属性
console.log(sub1.getName === sub2.getName) // true,复用了方法

优点:父类的方法(getName)得到了复用。

缺点:同理父类的属性(name)也是复用,即子类实例没有自己的属性。

二 构造函数实现继承

let Super = function(name = 'eric') {
this.name = name;
this.getName = function() {
return this.name;
}
}
let Sub = function(name, sex) {
Super.call(this, name);
this.sex = sex;
}
let sub1 = new Sub('eric', 'male');
let sub2 = new Sub('ada', 'female');
console.log(sub1.name) // 'eric'
console.log(sub1.hasOwnProperty('name')) // true 说明不是继承而来,是自己的属性
console.log(sub1.getName === sub2.getName) // false 方法没有得到复用

优点:子类的每个实例都有自己的属性(name),不会相互影响。

缺点:但是继承父类方法的时候就不需要这种特性,没有实现父类方法的复用。

三 组合式继承

let Super = function(name = 'eric') {
this.name = name;
}
Super.prototype = {
constructor: Super,
getName() {
return this.name;
}
}
let Sub = function(sex) {
Super.call(this, 'eric'); //继承父类属性
this.sex = sex;
}
Sub.prototype = new Super('eric'); //继承父类方法
Sub.prototype.constructor = Sub;
let sub1 = new Sub('male'),
sub2 = new Sub('female');
console.log(sub1.name); // 'eric'
console.log(sub1.hasOwnProperty('name')); // true 自己的属性
console.log(sub1.getName === sub2.getName); // true 复用了方法
console.log(Sub.prototype) // { name: "eric" }
console.log(sub1) // { name: "eric", sex: "male" }

优点:继承了上述两种方式的优点,摒弃了缺点,复用了方法,子类又有各自的属性。

缺点:因为父类构造函数被执行了两次,子类的原型对象(Sub.prototype)中也有一份父类的实例属性(name),而且这些属性会被子类实例(sub1,sub2)的属性覆盖掉(即通过sub1.name访问不到Sub.prototype上的name属性),也存在内存浪费。

四 寄生组合式继承

let Super = function(name = 'eric') {
this.name = name;
}
Super.prototype = {
constructor: Super,
getName() {
return this.name;
}
}
let Sub = function(sex, name) {
Super.call(this, name);
this.sex = sex;
}
// 组合继承的缺点就是在继承父类方法的时候调用了父类构造函数,从而造成内存浪费,
// 现在只要解决了这个问题就完美了。那在复用父类方法的时候,
// 使用Object.create方法也可以达到目的,没有调用父类构造函数,问题解决。
Sub.prototype = Object.create(Super.prototype);
// 当然这个地方也可以使用Object.setPrototypeOf(Sub.prototype, Super.prototype)
// 因为更改一个对象的隐士原型(__proto__)对浏览器和js引擎都是很慢对操作,所以建议使用Object.create()创建一个具有指定原型对象的新对象
Sub.prototype.constructor = Sub;

五 es6中的class

class Super() {
constructor(props = { name: 'eric' }) {
this.name = props.name;
}
setName(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Sub extends Super {
constructor(props) {
super(props = { sex: 'male' }); // 创建实例,继承父类属性和方法
this.sex = props.sex;
}
}
let sub1 = new Sub({
name: 'eric',
sex: 'male'
})
let sub2 = new Sub({
name: 'eric',
sex: 'female'
}) sub1.setName('ada');
console.log(sub1.getName(),sub2.getName()) // ada,eric,属性没复用,各自实例都有自己的属性。
console.log(sub1.getName === sub2.getName) // true; 复用了父类的方法
console.log(Sub.prototype.sex) // undefined
// 子类原型对象上没有父类构造函数中赋值的属性,不是组合式继承

由以上结果可以看到es6中的class只不过是一种语法糖,通过上面的验证得知符合寄生组合继承的特点,但这只是猜测,class具体都做了哪些操作还不是很清楚,后面有时间,对class做一下研究。

javascript中各种继承方式的优缺点的更多相关文章

  1. javascript中创建对象的方式及优缺点(一)

    1. 简单方式创建对象 // 字面量方式创建对象 var person1 = { name: "xyc", age: 23, sayHi: function() { console ...

  2. javascript中创建对象的方式及优缺点(二)

    一.工厂模式 流程: 定义一个函数,函数返回对象. 适用场景: 需要创建多个对象,都是Object类型. 优点:完成了返回一个对象的要求. 缺点: 对象没有一个具体的类型,无法通过constructo ...

  3. javascript中实现继承的几种方式

    javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Chi ...

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

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

  5. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  6. 浅谈JavaScript中的继承

    引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...

  7. 浅谈 JavaScript 中的继承模式

    最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...

  8. JS中对象继承方式

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

  9. JavaScript 的对象继承方式,有几种写法?

    JavaScript 的对象继承方式,有几种写法? 一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Pa ...

随机推荐

  1. 一篇文章看懂Facebook和新浪微博的智能FEED

    本文来自网易云社区 作者:孙镍波 众所周知,新浪微博的首页动态流不像微信朋友圈是按照时间顺序排列的,而是按照一种所谓的"智能排序"的方式.这种违背了用户习惯的排序方式一直被用户骂, ...

  2. leetcode 【 Remove Duplicates from Sorted Array 】python 实现

    题目: Given a sorted array, remove the duplicates in place such that each element appear only once and ...

  3. MongoDB快速入门学习笔记6 MongoDB的文档删除操作

    db.集合名称.remove({query}, justOne)query:过滤条件,可选justOne:是否只删除查询到的第一条数据,值为true或者1时,只删除一条数据,默认为false,可选. ...

  4. Python-S9-Day115——Flask Web框架基础

    01 今日内容概要 02 内容回顾 03 Flask框架:配置文件导入原理 04 Flask框架:配置文件使用 05 Flask框架:路由系统 06 Flask框架:请求和响应相关 07 示例:学生管 ...

  5. JavaWeb笔记(一)JDBC

    基本步骤 导入MySQL驱动jar包 mysql-connector-java-8.0.15.zip 注册驱动 获取数据库连接对象Connection 定义sql 获取执行sql语句的对象Statem ...

  6. nyoj 题目14 会场安排问题

    会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工 ...

  7. 【转】 [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)

    http://blog.csdn.net/pleasecallmewhy/article/details/8543181 在Unity中的数据存储和iOS中字典的存储基本相同,是通过关键字实现数据存储 ...

  8. [USACO12Jan][luogu3041] Video Game Combos [AC自动机+dp]

    题面 传送门 思路 首先,有一个非常显然的思路就是dp: 设$dp[i][j]$表示前i个字符,最后一个为j 然后发现这个东西有后效性 改!设$dp[i][j]$代表前i个字符,最后15个的状态为j( ...

  9. Idea插件lombok的安装和使用

    C#在写一个实体类时,有属性的写法,省去了写getter和setter的麻烦. 在Java编程时,写完字段后,需要一个一个去写getter和setter方法.在使用Idea编程时,可以按住ALT+IN ...

  10. js 如何生成一个不重复的ID的函数

    在MongoDB中的ObjectID,可以理解为是一个不会重复的ID,这里有个链接http://www.jb51.net/article/101164.htm感兴趣可以去研究一下. 我今天要做的就是做 ...