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困惑—包装集 DOM节点
Oct 16 Javascript
JavaScript 操作table,可以新增行和列并且隔一行换背景色代码分享
Jul 05 Javascript
JS和JQ的event对象区别分析
Nov 24 Javascript
node.js中的console.log方法使用说明
Dec 09 Javascript
jQuery原生的动画效果
Jul 10 Javascript
深入理解Javascript中的自执行匿名函数
Jun 03 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
Jan 05 Javascript
微信小程序 弹框和模态框实现代码
Mar 10 Javascript
详解vue2 $watch要注意的问题
Sep 08 Javascript
从零开始搭建webpack+react开发环境的详细步骤
May 18 Javascript
详解nuxt路由鉴权(express模板)
Nov 21 Javascript
Vue 列表页带参数进详情页的操作(router-link)
Nov 13 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
利用PHP和AJAX创建RSS聚合器的代码
2007/03/13 PHP
使用PHP获取当前url路径的函数以及服务器变量
2013/06/29 PHP
Symfony2实现从数据库获取数据的方法小结
2016/03/18 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
[原创]提供复制本站内容时出现,该文章转自脚本之家等字样的js代码
2007/03/27 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
招聘网站基于jQuery实现自动刷新简历
2015/05/10 Javascript
javascript基于DOM实现权限选择实例分析
2015/05/14 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
Javascript 实现放大镜效果实例详解
2016/12/03 Javascript
JS中正则表达式全局匹配模式 /g用法详解
2017/04/01 Javascript
vue如何从接口请求数据
2017/06/22 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
详解react-native WebView 返回处理(非回调方法可解决)
2018/02/27 Javascript
JS中验证整数和小数的正则表达式
2018/10/08 Javascript
JS实现的获取银行卡号归属地及银行卡类型操作示例
2019/01/08 Javascript
vue element动态渲染、移除表单并添加验证的实现
2019/01/16 Javascript
JS访问对象两种方式区别解析
2020/08/29 Javascript
Vue封装全局过滤器Filters的步骤
2020/09/16 Javascript
用Nodejs实现在终端中炒股的实现
2020/10/18 NodeJs
[03:27]最受玩家喜爱奖提名:PZH_Element 致玩家寄语
2016/12/20 DOTA
[36:43]NB vs Optic 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
2015/04/05 Python
python矩阵的转置和逆转实例
2018/12/12 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
Python3多目标赋值及共享引用注意事项
2019/05/27 Python
个性与发展自我评价
2014/02/11 职场文书
六一节目主持词
2014/04/01 职场文书
爱情寄语大全
2014/04/09 职场文书
大学学雷锋活动总结
2014/06/26 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
开展党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
2014年反腐倡廉工作总结
2014/12/05 职场文书
毕业酒会致辞
2015/07/29 职场文书
2016高三毕业赠言寄语
2015/12/04 职场文书
bose降噪耳机音能消除人声吗
2022/04/19 数码科技