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 相关文章推荐
用javascript父窗口控制只弹出一个子窗口
Apr 10 Javascript
Extjs 几个方法的讨论
Jan 28 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
Jul 05 Javascript
jQuery实现的跨容器无缝拖动效果代码
Jun 21 Javascript
jQuery文字提示与图片提示效果实现方法
Jul 04 Javascript
归纳下js面向对象的几种常见写法总结
Aug 24 Javascript
微信js-sdk上传与下载图片接口用法示例
Oct 12 Javascript
JavaScript中关键字 in 的使用方法详解
Oct 17 Javascript
jQuery内存泄露解决办法
Dec 13 Javascript
jQuery Raty星级评分插件使用方法实例分析
Nov 25 jQuery
JS window对象简单操作完整示例
Jan 14 Javascript
Vue封装Axios请求和拦截器的步骤
Sep 16 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在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
PHP isset()与empty()的使用区别详解
2010/08/29 PHP
PHP防盗链的基本思想 防盗链的设置方法
2015/09/25 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
2016/03/29 PHP
php源码之将图片转化为data/base64数据流实例详解
2016/11/27 PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
2019/09/30 PHP
thinkphp框架表单数组实现图片批量上传功能示例
2020/04/04 PHP
10个基于Jquery的幻灯片插件教程
2010/10/29 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
ie支持function.bind()方法实现代码
2012/12/27 Javascript
JavaScript中“基本类型”之争小结
2013/01/03 Javascript
jQuery中cookie插件用法实例分析
2015/12/04 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
mint-ui的search组件在键盘显示搜索按钮的实现方法
2017/10/27 Javascript
js 数组详细操作方法及解析合集
2018/06/01 Javascript
axios简单实现小程序延时loading指示
2018/07/30 Javascript
Vue 动态添加路由及生成菜单的方法示例
2019/06/20 Javascript
Python同时向控制台和文件输出日志logging的方法
2015/05/26 Python
python实现将文本转换成语音的方法
2015/05/28 Python
python使用生成器实现可迭代对象
2018/03/20 Python
Python 爬取携程所有机票的实例代码
2018/06/11 Python
windows下的pycharm安装及其设置中文菜单
2020/04/23 Python
Expedia意大利旅游网站:酒店、机票和租车预订
2017/10/30 全球购物
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
迪斯尼假期(欧洲、中东及非洲):Disney Holidays EMEA
2021/02/15 全球购物
消防应急演练方案
2014/02/12 职场文书
上课看小说检讨书
2014/02/22 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
财务情况说明书范文
2014/05/06 职场文书
关于迟到的检讨书
2015/05/06 职场文书
2015年学校安全管理工作总结
2015/05/11 职场文书
学生早退检讨书(范文)
2019/08/19 职场文书
发工资啦!教你用Python实现邮箱自动群发工资条
2021/05/10 Python
css filter和getUserMedia的联合使用
2022/02/24 HTML / CSS
Python使用mitmproxy工具监控手机 下载手机小视频
2022/04/18 Python