js继承的这6种方式!(上)


Posted in Javascript onApril 23, 2019

写在前面

继承的简介

继承”是JavaScript面向对象设计的重要一环,愿你认真读完本文,吃透继承的概念。

继承的核心

js继承的这6种方式!(上)

1. 继承方式一:原型链

1.1 介绍

原型链是实现继承最原始的模式,即通过prototype属性实现继承。

//父级-构造函数
function Father() {
 this.fatherProp = true
}

//父级-原型属性
Father.prototype.getFatherValue = function() {
 return this.fatherProp
}

//子级-构造函数
function Son() {
 this.sonProp = false
}

//子级-原型属性:继承父级
//即__proto__指向父级的prototype
//若不理解请阅读《一张图彻底KO原型链(prototype,__proto__》
Son.prototype = new Father()

//子级-添加原型方法
Son.prototype.getSonValue = function() {
 return this.sonProp
}

//创建子级的实例对象
var son = new Son()
console.log(son.getFatherValue()) //true

1.2 解析:son实例对象是如何找到getFatherValue()方法的呢?

  1. 首先在son对象自身中找。若对象自身没找到
  2. 然后在Son.prototype中找。若Son.prototype中没找到
  3. 继续往上一层,Son.prototype.__proto__(Fater.prototype)
  4. 依次类推,直到找到需要的属性或方法,或到达原型链顶端Object.prototype

如果到最后都没找到,会发生什么呢?

//一个不存在的方法
console.log(son.getValue()) //ERROE:not a function

1.3 注意事项

重写父级原型链的方法或者添加父级原型链不存在的方法,必须在父级原型链代码之后。(这个很好理解,不放代码演示了)

通过原型链实现继承后,不能再使用字面量的方式创建原型对象,因为会覆盖原型链。

//子级-原型属性:继承父级
Son.prototype = new Father()

//不能像下面这样,这样会使得上面的代码无效
//因为这相当于重新创建了一个原型对象
Son.prototype = {
 getSonValue: function() {
  return this.sonProp
 }
}

1.4 原型链实现继承的弊端

世间万事万物都不可能十全而十美,原型链虽然强大,但也存在缺陷。

原型链中引用类型的属性会被所有实例共享的,即所有实例对象使用的是同一份数据,会相互影响。

function Father() {
  this.arr = [1,2,3]
 }

 function Son() {
 }

 Son.prototype = new Father()

 var son1 = new Son()
 console.log(son1.arr) //1,2,3

 var son2 = new Son()
 son2.arr.push(4)

 console.log(son2.arr) //1,2,3,4
 console.log(son1.arr) //1,2,3,4

无法向父级构造函数传参

2. 继承方式二:借用构造函数

2.1 介绍

方式一中引用类型带来的问题可借用构造函数的方式解决。其核心思想是:在子级构造函数中调用父级构造函数。

如何实现在一个构造函数中调用另一个函数?——call()和apply()

function Father() {
  this.arr = [1,2,3]
 }

 function Son() {
  //call的第一个函数是this指向的对象,即构造函数的实例对象
  Father.call(this)

  /*上面代码等同于下面这段代码:
  (function() {
   this.arr = [1,2,3]
  }).call(this)
  */
 }

 var son1 = new Son()
 console.log(son1.arr) //1,2,3

 var son2 = new Son()
 son2.arr.push(4)

 console.log(son2.arr) //1,2,3,4
 console.log(son1.arr) //1,2,3
//解决传参问题:
function Father(name) {
 this.name = name
}

function Son(name) {
 Father.call(this, name)
}

var son1 = new Son("小名")
console.log(son1.name)  //小名

var son2 = new Son("一灯")
console.log(son2.name)  //一灯

2.2 借用构造函数的缺陷

这种方式是通过构造函数实现的,当然也把构造函数自身的问题带过来了——破坏了复用性。因为每个实例都创建了一份副本。

3. 组合继承

3.1 介绍

组合继承 = 原型链 + 借用构造函数。取其长避其短:共享的用原型链,各自的借用构造函数

function Father(name) {
 this.name = name
 this.arr = [1,2,3]
}

Father.prototype.getName = function() {
 console.log(this.name)
}

function Son(name, age) {
 Father.call(this, name)
 this.age = age
}

Son.prototype = new Father()
Son.prototype.constructor = Son
Son.prototype.getAge = function() {
 console.log(this.age)
}

var son1 = new Son("小名", 23)
son1.arr.push(4)
console.log(son1.arr) //1,2,3,4
son1.getName()    //小名
son1.getAge()     //23

var son2 = new Son("一灯", 24)
console.log(son2.arr) //1,2,3
son1.getName()    //一灯
son1.getAge()     //24

3.2 解析

借用构造函数部分:

Father.call(this, name)——name来自Father
this.age = age; Son.prototype.constructor = Son——age来自Son

原型链部分:

Father.prototype.getName——getName方法来自Father.prototype
Son.prototype.getAge——getAge来自Son.prototype

后记

关于继承的后三种方式马上推出,期待你的点赞&关注!

以上所述是小编给大家介绍的js继承方式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery代码优化之基本事件
Nov 01 Javascript
jQuery弹性滑动导航菜单实现思路及代码
May 02 Javascript
js获取dom的高度和宽度(可见区域及部分等等)
Jun 13 Javascript
父页面显示遮罩层弹出半透明状态的dialog
Mar 04 Javascript
JavaScript 学习笔记之数据类型
Jan 14 Javascript
node 利用进程通信实现Cluster共享内存
Oct 27 Javascript
JavaScript的Object.defineProperty详解
Jul 09 Javascript
微信小程序实现滴滴导航tab切换效果
Jul 24 Javascript
JavaScript对JSON数组简单排序操作示例
Jan 31 Javascript
简单了解JavaScript sort方法
Nov 25 Javascript
高性能js数组去重(12种方法,史上最全)
Dec 21 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
Sep 10 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
Apr 23 #jQuery
node.js基于socket.io快速实现一个实时通讯应用
Apr 23 #Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
Apr 23 #Javascript
vue 中 beforeRouteEnter 死循环的问题
Apr 23 #Javascript
JavaScript中十种一步拷贝数组的方法实例详解
Apr 22 #Javascript
vue watch关于对象内的属性监听
Apr 22 #Javascript
vue项目中仿element-ui弹框效果的实例代码
Apr 22 #Javascript
You might like
构建简单的Webmail系统
2006/10/09 PHP
php daodb插入、更新与删除数据
2009/03/19 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
怎么在Windows系统中搭建php环境
2013/08/31 PHP
smarty模板局部缓存方法使用示例
2014/06/17 PHP
php中实现精确设置session过期时间的方法
2014/07/17 PHP
微信公众平台实现获取用户OpenID的方法
2015/04/15 PHP
php 遍历目录,生成目录下每个文件的md5值并写入到结果文件中
2016/12/12 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
让Firefox支持event对象实现代码
2009/11/07 Javascript
网页中的图片的处理方法与代码
2009/11/26 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
2016/08/15 Javascript
JavaScript实战(原生range和自定义特效)简单实例
2016/08/21 Javascript
[原创]JS基于FileSaver.js插件实现文件保存功能示例
2016/12/08 Javascript
javascript动画系列之模拟滚动条
2016/12/13 Javascript
使用JavaScript中的lodash编写双色球效果
2018/06/24 Javascript
vue删除html内容的标签样式实例
2018/09/13 Javascript
nodejs中用npm初始化来创建package.json的实例讲解
2018/10/10 NodeJs
微信小程序实现左滑修改、删除功能
2020/10/19 Javascript
vue调试工具vue-devtools安装及使用方法
2018/11/07 Javascript
js实现复制粘贴的两种方法
2020/12/04 Javascript
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
[03:08]迎霜节狂欢!2018年迎霜节珍藏Ⅰ一览
2018/12/25 DOTA
python中Flask框架简单入门实例
2015/03/21 Python
Python文件的读写和异常代码示例
2017/10/31 Python
matplotlib 输出保存指定尺寸的图片方法
2018/05/24 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
在Python中使用Neo4j的方法
2019/03/14 Python
利用python计算windows全盘文件md5值的脚本
2019/07/27 Python
Python-opencv实现红绿两色识别操作
2020/06/04 Python
Html5无刷新修改browser Url的方法
2014/01/15 HTML / CSS
新闻简讯格式及范文
2015/07/22 职场文书
php png失真的原因及解决办法
2021/10/24 PHP
vue ant design 封装弹窗表单的使用
2022/06/01 Vue.js
oracle delete误删除表数据后如何恢复
2022/06/28 Oracle