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 相关文章推荐
ajax 缓存 问题 requestheader
Aug 01 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
一个网页标题title的闪动提示效果实现思路
Mar 22 Javascript
浅谈Jquery核心函数
Jun 18 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
Aug 18 Javascript
jquery及js实现动态加载js文件的方法
Jan 21 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
Feb 02 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
Nov 05 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
Jan 22 Javascript
vue.js自定义组件directives的实例代码
Nov 09 Javascript
微信小程序常见页面跳转操作简单示例
May 01 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
Jul 20 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+xml实现在线英文词典之添加词条的方法
2015/01/23 PHP
使用PHP开发留言板功能
2019/11/19 PHP
JavaScript中的闭包原理分析
2010/03/08 Javascript
jquery DOM操作 基于命令改变页面
2010/05/06 Javascript
js跨域问题之跨域iframe自适应大小实现代码
2010/07/17 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
jquery实现不包含当前项的选择器实例
2015/06/25 Javascript
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
JS版元素周期表实现方法
2015/08/05 Javascript
JavaScript中的this关键字使用详解
2015/08/14 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
详解js的事件处理函数和动态创建html标记方法
2016/12/16 Javascript
JavaScript正则替换HTML标签功能示例
2017/03/02 Javascript
详解如何实现一个简单的 vuex
2018/02/10 Javascript
vue中关闭eslint的方法分析
2018/08/04 Javascript
vue中的router-view组件的使用教程
2018/10/23 Javascript
Javascript中的this,bind和that使用实例
2019/12/05 Javascript
小程序使用wxs解决wxml保留2位小数问题
2019/12/13 Javascript
[01:02:04]EG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python 中的列表解析和生成表达式
2011/03/10 Python
python开发的小球完全弹性碰撞游戏代码
2013/10/15 Python
Python使用新浪微博API发送微博的例子
2014/04/10 Python
用Python进行基础的函数式编程的教程
2015/03/31 Python
Apache如何部署django项目
2017/05/21 Python
python requests 使用快速入门
2017/08/31 Python
解决python web项目意外关闭,但占用端口的问题
2019/12/17 Python
python mongo 向数据中的数组类型新增数据操作
2020/12/05 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
意大利顶级奢侈品电商:LUISAVIAROMA(支持中文)
2020/05/26 全球购物
六年级学生评语大全
2014/12/26 职场文书
违规违纪检讨书范文
2015/05/06 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书
python中sqllite插入numpy数组到数据库的实现方法
2021/06/21 Python
Python开发简易五子棋小游戏
2022/05/02 Python