设计模式什么的根本记不住啊 , 直接看各类原生JS继承吧!!!
栏目: JavaScript · 发布时间: 5年前
内容简介:不要讲什么设计模式 , 看得老子脑壳昏 , 智商欠费 , 还是简单点 , 方案 , 继承 , 就完事了OK, 我们现在有了一个父类, 先来看一个最简单的继承
不要讲什么设计模式 , 看得老子脑壳昏 , 智商欠费 , 还是简单点 , 方案 , 继承 , 就完事了
// 首先我们得有个父类 // 这个父类也很简单 function Human(name) { this.name = name || '肥宅' // 有参就取参 , 没参就叫肥宅 } Human.prototype.drink = function(drinks) { console.log(this.name + '正在喝' + (drinks || '可乐')); } 复制代码
OK, 我们现在有了一个父类, 先来看一个最简单的继承
最简单的原型链继承
直接把父类的实例作为子类的原型
// 先写个空类 function Jianren(){} Jianren.prototype = new Human() // new个实例看看 var haidong = new Jianren(); console.log(haidong.name); //'肥宅' console.log(haidong.drink()); //'haidong正在喝可乐' 复制代码
对于这个继承, 概括为子类的原型链绑定父类的实例实现继承
缺陷
- 不能实现多类继承
- 为子类新增属性和方法,必须要在new Animal()这样的语句之后执行
- 无法控制子类能够访问父类属性的权限
- 创建子类的实例时也不能向父类构造函数传参
构造继承
复制父类属性
function Jianren(){ Human.call(this);// 把父类写进子类构造函数内部, 调用call把子类的this传进去改变this的指向做到复制父类属性 this.age = 22 } 复制代码
- 构造继承其实就是复制了父类属性, new Jianren()出来的实例的construct和prototype都与Human无关, 指向Jianren()
- 可以不管new 父类前后顺序来新增子类的属性
- 创建子类实例时, 也可以向父类传递参数,
- 可以call多个父类实现多类继承
- 只能继承父类的实例属性和方法, 不能继承/访问到父类原型上的东西
- 难以复用, 影响性能
实例继承
在子类内部添加一个属性, 该属性为父类的实例
function Jianren(name){ var ren = new Human();// 注意这里是不是this ren.name = name || 'haidong'; return ren; } 复制代码
- 不会限制调用的方式, new 子类() 或者 子类()执行, 都返回ren
- new Jianren()的实例实际上是new Human(), constructor也是指向Human()
- 不支持多类继承
拷贝继承
function Jianren(name){ var ren = new Human() for(var r in ren) { Cat.prototype[r] = ren[r] // 该处r是key, 应该用Object[key]的形式赋值和访问 } Jianren.prototype.name = name || 'haidong' } 复制代码
- 支持多继承
- 效率低, 拷贝属性会占用内存
- 不可枚举父类
推荐的两种继承
组合继承和寄生组合继承
上面的继承主要是帮助理解, 或有时暴力快速解决小问题时使用 .
推荐一, 组合继承
子类的原型指向父类实例,该父类实例又可向上原型查找访问,修正后constructor指向子类自身
function Jianren(name) { Human.call(this) //第一步拷贝属性 this.name = name || 'haidong' } Jianren.prototype = new Human() //第二步, 原型指向父类实例 Jianren.prototype.constructor = Jianren //第三步, 修正constructor指向 复制代码
- 可以继承实例的属性/方法, 也可以继承原型的属性方法,
- 是子类的实例, 也相当于是父类的实例
- 子类的原型指向父类实例,该父类实例又可向上原型查找访问,修正后constructor指向子类自身
- 可传参,//call()可以传参,具体用法,自行百度谷歌
- 调用两次父类构造函数, 占内存, 第一步拷贝过一次, 第二步导致以后的Jianren的实例里和Jianren原型上重复的属性
推荐二, 寄生组合继承
// 有点复杂 function Jianren(name) { Human.call(this) //第一步拷贝属性 this.name = name || 'haidong' } (function() { //来个匿名立即执行函数 function J() {}// 创建一个中间类, 空, 什么都没有 J.prototype = Human.prototype //第二步中间类原型指向父类原型 Jianren.prototype = new J() //子类原型赋值为中间类的实例,往上查找,指向了父类的原型 })() Jianren.prototype.constructor = Jianren //修正子类constructor指向 复制代码
与上面的组合继承相比, 第一步拷贝 和 第二步中间类(空类)不会重复有Human的属性, 略微复杂, 可以忽略不计, 完美方式
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式-享元设计模式
- 设计模式(四)Singleton设计模式
- 设计模式之建造者设计模式
- 设计模式之单例设计模式
- 设计模式(2)- 深入浅出设计模式 阅读笔记
- 设计模式(1)- 深入浅出设计模式 阅读笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。