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 输入框内容格式验证代码
Feb 11 Javascript
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
Jun 28 Javascript
表头固定(利用jquery实现原理介绍)
Nov 08 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
Apr 29 Javascript
Javascript中的五种数据类型详解
Dec 26 Javascript
谈谈impress.js初步理解
Sep 09 Javascript
Vue.js 60分钟快速入门教程
Mar 28 Javascript
Cpage.js给组件绑定事件的实现代码
Aug 31 Javascript
浅谈react前后端同构渲染
Sep 20 Javascript
jQuery中复合选择器简单用法示例
Mar 31 jQuery
vue组件实现进度条效果
Jun 06 Javascript
vuex页面刷新导致数据丢失的解决方案
Dec 10 Vue.js
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
风格模板初级不完全修改教程
2006/10/09 PHP
php环境配置 php5 MySQL5 apache2 phpmyadmin安装与配置图文教程
2007/03/16 PHP
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
令PHP初学者头疼十四条问题大总结
2008/11/12 PHP
PHP,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
关于Javascript与iframe的那些事儿
2013/07/04 Javascript
js调试系列 控制台命令行API使用方法
2014/06/18 Javascript
javascript与jquery中的this关键字用法实例分析
2015/12/24 Javascript
javascript返回顶部的按钮实现方法
2016/01/09 Javascript
使用 stylelint检查CSS_StyleLint
2016/04/28 Javascript
使用json来定义函数,在里面可以定义多个函数的实现方法
2016/10/28 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
AngularJS实现进度条功能示例
2017/07/05 Javascript
vue vuex vue-rouert后台项目——权限路由(适合初学)
2017/12/29 Javascript
JS表单传值和URL编码转换
2018/03/03 Javascript
JavaScript图片处理与合成总结
2018/03/04 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
JS控制只能输入数字并且最多允许小数点两位
2019/11/24 Javascript
Vue router安装及使用方法解析
2020/12/02 Vue.js
[14:36]2014 DOTA2国际邀请赛中国区预选赛5.21 Orenda VS NE
2014/05/22 DOTA
[00:03]DOTA2新版本PA至宝展示
2014/11/19 DOTA
跟老齐学Python之玩转字符串(2)
2014/09/14 Python
Python中实现从目录中过滤出指定文件类型的文件
2015/02/02 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
python正则表达式爬取猫眼电影top100
2018/02/24 Python
Linux下python3.6.1环境配置教程
2018/09/26 Python
Python实现针对json中某个关键字段进行排序操作示例
2018/12/25 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
2020/05/25 Python
html5基础标签(html5视频标签 html5新标签用法)
2013/12/30 HTML / CSS
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
为什么在使用动态 SQL 语句时必须为低层数据库对象授予权限
2012/12/13 面试题
2014年创卫工作总结
2014/11/24 职场文书
研讨会致辞
2015/07/31 职场文书
pandas中关于apply+lambda的应用
2022/02/28 Python