2-JavaScript设计模式——commonUtils工具库之继承函数

在学习 JavaScript 设计模式之前,我们先做一个 commonUtils 工具库,以便于后期的学习和使用。


 commonUtils 工具库包括:多维数组遍历,继承函数,接口类及其验证。


本章为继承函数:

☞ 继承的实现

// 继承的实现包含以下步骤
// 定义一个父类的模板(构造器)
function Sup(name, age){
  this.name = name;
  this.age = age;
}

// 为父类添加原型方法
Sup.prototype = {
  /*
    注意:这里一定要重新定义构造器
      因为 {} 代表的是一个单体对象,其构造器为Object,所以需要重新定义构造器为Sup;
      但实际开发中,经常会有忘记重新定义构造器,我们将在继承函数中规避这一问题。
  */
  constructor : Sup,
  eat : function(){
    alert(this.name + ' 正在吃饭...');
  },
  sleep : function(){
    alert(this.name + ' 正在睡觉...');
  }
};

// 定义一个子类的模板
// 注意:父类传递的参数,子类也要传递
function Sub(name, age, sex){
  // 继承父类的模板,即 将父类的模板绑定到子类的模板的作用域中
  Sup.call(this, name, age);
  this.sex = sex;
}

/*
  1、让子类继承父类,即 让子类的原型对象 等于 父类的实例,于是 子类同时继承了父类的模板和原型对象。
  2、父类实例不能传参,否则子类所继承自父类的属性就被固化了。
  3、这样存在一个问题,这里继承一次父类模板,子类作用域中又继承了一次父类模板,一共继承了两次,如果父类属性成员较多,则会影响性能,我们将在继承函数中解决这一问题。
*/
Sub.prototype = new Sup(); 
/*
 构造函数 原型对象 实例对象 之间的关系
  1、构造函数.prototype = 原型对象
  2、原型对象.constructor = 构造函数(模板)
  3、原型对象.isPrototypeOf(实例对象) 判断实例对象的原型 是不是当前对象
  4、构造函数 <=> 实例对象 (类和实例)
*/


☞  继承函数

// 命名空间
var JG = {};

// 继承函数。 传参:sub 子类;sup 父类。
JG.extend = function(sub, sup){
  // 创建一个中间类 F
  function F(){}
  
  F.prototype = sup.prototype;
  
  /*
    让子类继承中间类 F, 这样子类继承了 中间类的构造器(空的模板)和原型对象,解决了 两次继承父类模板问题 对性能的影响
  */
  sub.prototype = new F();
  
  // 将子类的构造器 改回 子类本身
  sub.prototype.constructor = sub;
  
  // 为子类定义一个 superClass 属性,值为父类的原型对象,这样在子类中可以通过调用 superClass 属性来代替父类的原型对象,从而实现解耦的目的。
  sub.superClass = sup.prototype;
  
  // 如果父类构造器为,Object,则更改为 父类本身,从而解决 忘记重新定义构造器问题。
  if(sup.prototype.constructor === Object.prototype.constructor){
    sup.prototype.constructor = sup;
  }
};

// 测试
// 父类
function Person(name, age){
  this.name = name;
  this.age = age;
}

// 父类原型对象
Person.prototype = {
  constructor : Person,
  eat : function(){
    alert(this.name + ' 正在吃饭...');
  },
  sleep : function(){
    alert(this.name + ' 正在睡觉...');
  }
};

// 子类
function Student(name, age, sex){
  // 继承父类模板
  Student.superClass.constructor.call(this, name, age);
  this.sex = sex;
}

// 继承
JG.extend(Student, Person);

// 扩展子类原型对象 注意:必须写在继承后面,否则会被重置清空
Student.prototype.study = function(){
  alert(this.name + ' 正在学习...');
};

// 实例
var zhangSan = new Student('zhangSan', 18, '男');

document.write(zhangSan.name + ': ' + zhangSan.age + ', ' + zhangSan.sex + '

');//zhangSan: 18, 男 zhangSan.eat(); // zhangSan 正在吃饭... zhangSan.sleep(); // zhangSan 正在睡觉... zhangSan.study(); // zhangSan 正在学习...


你可能感兴趣的:(JavaScript设计模式)