写在前面
继承的简介
继承”是JavaScript面向对象设计的重要一环,愿你认真读完本文,吃透继承的概念。
继承的核心
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()方法的呢?
- 首先在son对象自身中找。若对象自身没找到
- 然后在Son.prototype中找。若Son.prototype中没找到
- 继续往上一层,Son.prototype.__proto__(Fater.prototype)
- 依次类推,直到找到需要的属性或方法,或到达原型链顶端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继承方式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]