设计模式什么的根本记不住啊 , 直接看各类原生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正在喝可乐'
复制代码

对于这个继承, 概括为子类的原型链绑定父类的实例实现继承

缺陷

  1. 不能实现多类继承
  2. 为子类新增属性和方法,必须要在new Animal()这样的语句之后执行
  3. 无法控制子类能够访问父类属性的权限
  4. 创建子类的实例时也不能向父类构造函数传参

构造继承

复制父类属性

function Jianren(){
  Human.call(this);// 把父类写进子类构造函数内部, 调用call把子类的this传进去改变this的指向做到复制父类属性
  this.age = 22
}
复制代码
  1. 构造继承其实就是复制了父类属性, new Jianren()出来的实例的construct和prototype都与Human无关, 指向Jianren()
  2. 可以不管new 父类前后顺序来新增子类的属性
  3. 创建子类实例时, 也可以向父类传递参数,
  4. 可以call多个父类实现多类继承
  5. 只能继承父类的实例属性和方法, 不能继承/访问到父类原型上的东西
  6. 难以复用, 影响性能

实例继承

在子类内部添加一个属性, 该属性为父类的实例

function Jianren(name){
  var ren = new Human();// 注意这里是不是this
  ren.name = name || 'haidong';
  return ren;
}
复制代码
  1. 不会限制调用的方式, new 子类() 或者 子类()执行, 都返回ren
  2. new Jianren()的实例实际上是new Human(), constructor也是指向Human()
  3. 不支持多类继承

拷贝继承

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'
}
复制代码
  1. 支持多继承
  2. 效率低, 拷贝属性会占用内存
  3. 不可枚举父类

推荐的两种继承

组合继承和寄生组合继承

上面的继承主要是帮助理解, 或有时暴力快速解决小问题时使用 .

推荐一, 组合继承

子类的原型指向父类实例,该父类实例又可向上原型查找访问,修正后constructor指向子类自身

function Jianren(name) {
    Human.call(this) //第一步拷贝属性
    this.name = name || 'haidong'
}
Jianren.prototype = new Human() //第二步, 原型指向父类实例
Jianren.prototype.constructor = Jianren //第三步, 修正constructor指向
复制代码
  1. 可以继承实例的属性/方法, 也可以继承原型的属性方法,
  2. 是子类的实例, 也相当于是父类的实例
  3. 子类的原型指向父类实例,该父类实例又可向上原型查找访问,修正后constructor指向子类自身
  4. 可传参,//call()可以传参,具体用法,自行百度谷歌
  5. 调用两次父类构造函数, 占内存, 第一步拷贝过一次, 第二步导致以后的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的属性, 略微复杂, 可以忽略不计, 完美方式


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Black Box Society

The Black Box Society

Frank Pasquale / Harvard University Press / 2015-1-5 / USD 35.00

Every day, corporations are connecting the dots about our personal behavior—silently scrutinizing clues left behind by our work habits and Internet use. The data compiled and portraits created are inc......一起来看看 《The Black Box Society》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试