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 相关文章推荐
Auntion-TableSort国人写的一个javascript表格排序的东西
Nov 12 Javascript
JQuery的read函数与js的onload不同方式实现
Mar 18 Javascript
用JavaScript实现动画效果的方法
Jul 20 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
Nov 22 Javascript
无闪烁更新网页内容JS实现
Dec 19 Javascript
Javascript的严格模式strict mode详细介绍
Jun 06 Javascript
基于JavaScript实现手机短信按钮倒计时(超简单)
Dec 30 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
Vue官方文档梳理之全局配置
Nov 22 Javascript
基于模板引擎Jade的应用(详解)
Dec 12 Javascript
JavaScript多态与封装实例分析
Jul 27 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
May 02 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
简单易用的计数器(数据库)
2006/10/09 PHP
模仿OSO的论坛(三)
2006/10/09 PHP
yii2超好用的日期组件和时间组件
2016/05/05 PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
2018/01/29 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
js获取下拉列表的值和元素个数示例
2014/05/07 Javascript
jQuery+css实现的tab切换标签(兼容各浏览器)
2016/01/28 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
2017/02/18 Javascript
借助node实战JSONP跨域实例
2017/03/30 Javascript
jQuery异步提交表单实例
2017/05/30 jQuery
详解React中的组件通信问题
2017/07/31 Javascript
jQuery超简单遮罩层实现方法示例
2018/09/06 jQuery
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
2019/04/22 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
JavaScript实现省份城市的三级联动
2020/02/11 Javascript
微信小程序 scroll-view的使用案例代码详解
2020/06/11 Javascript
操作Windows注册表的简单的Python程序制作教程
2015/04/07 Python
举例讲解Python中metaclass元类的创建与使用
2016/06/30 Python
深入浅出学习python装饰器
2017/09/29 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
2018/10/15 Python
python实现海螺图片的方法示例
2019/05/12 Python
python PIL和CV对 图片的读取,显示,裁剪,保存实现方法
2019/08/07 Python
Ranorex通过Python将报告发送到邮箱的方法
2020/01/12 Python
Django自定义全局403、404、500错误页面的示例代码
2020/03/08 Python
Selenium webdriver添加cookie实现过程详解
2020/08/12 Python
html5使用canvas画三角形
2014/12/15 HTML / CSS
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
美国打印机墨水和碳粉购物网站:QuikShip Toner
2018/08/29 全球购物
安全生产中长期规划实施方案
2014/02/21 职场文书
秋天的怀念教学反思
2014/04/28 职场文书
2016新年感言
2015/08/03 职场文书
家长对孩子的寒假评语
2015/10/09 职场文书
教你做个可爱的css滑动导航条
2021/06/15 HTML / CSS
html5表单的required属性使用
2021/07/07 HTML / CSS
JavaScript严格模式不支持八进制的问题讲解
2021/11/07 Javascript