JS继承、隔离、圣杯模式

108 阅读2分钟

继承、隔离、圣杯模式

继承

 // 继承
 ​
 Professor.prototype = {
   // 在这个Professor原型上加了两个属性
   name: "Mr. Zhang",
   tSkill: "JAVA",
 };
 ​
 function Professor() {} // 声明构造函数
 ​
 let professor = new Professor(); //它继承它的原型
 ​
 Teacher.prototype = professor; // 把Professor实例化对象绑定给Teacher构造函数的原型
 function Teacher() {
   this.name = "Mr. Wang";
   this.mSkill = "JS/JQ";
 }
 let teacher = new Teacher();
 ​
 //这样就能让Teacher这个构造函数实例化的所有对象都能继承professor对象的原型属性
  • applycall
 //call/apply
 function Teacher(name, mSkill) {
   this.name = name;
   this.mSkill = mSkill;
 }
 function Student(name, mSkill, age, major) {
   Teacher.apply(this, [name, mSkill]);
     // 在Student构造函数内把Student实例化的对象传给Teacher构造函数
   this.age = age;
   this.major = major;
 }

隔离

 //隔离
 function Buffer() {} // 中间对象的构造函数
 let buffer = new Buffer(); 
 Buffer.prototype = Teacher.prototype; // 绑定上层原型
 Student.prototype = buffer;  // 绑定下层原型
 Student.prototype.age = 18; // 不会影响到Teacher的属性
 ​
 // 这样不会出现绑定相同的原型带来的影响
 // 在两个上下层继承关系的对象中间加入一个中间对象,这样就不会相互影响
 // 企业也是这样做的,叫圣杯模式

封装隔离方法

 // 封装隔离
 ​
 function inherit(Target, Origin) {
   function Buffer() {}
   Buffer.prototype = Origin.prototype;
   Target.prototype = new Buffer();
   Target.prototype.constructor = Target; // 指示器
   Target.prototype.super_class = Origin; // 继承源
 }
 ​
 // inherit(子级对象,父级对象)直接能进行隔离的操作
  • 复习闭包
 //闭包
 function test() {
   let num = 0; // 私有变量
   function add() {
     num++;
     console.log(num);
   }
   return add;
 }
 let add = test();
 // 执行test函数就相当于执行test函数内的add函数
 // 由于test执行完后 add函数的AO不能销毁因为被return出去了
 // 所以num还能被add访问到 所以形成了闭包
  • 用闭包封装隔离方法
 // 用闭包做inherit方法
 ​
 let inherit = (function () {
   let Buffer = function () {};
   return function (Target, Origin) {
     Buffer.prototype = Origin.prototype;
     Target.prototype = new Buffer();
     Target.prototype.constructor = Target;
     Target.prototype.super_class = Origin;
   };
 })(); // 在页面加载的时候就执行这个函数

案例

 // 案例
 // 在函数内造了一个伪全局,不会污染外部的变量
 let initProgrammer = (function () {
   let Programmer = function () {};
   Programmer.prototype = {
     name: "程序员",
     tool: "计算机",
     work: "编写应用程序",
     duration: "10个小时",
     say: function () {
       console.log(
         "我是一名" + this.myName + this.name + ",我的工作是用" + this.tool + this.work +
           ",我每天工作" +  this.duration +   "小时,我的工作需要用到" +  this.lang.toString() +  "。"
       );
     },
   };
   function FrontEnd() {}
   function BackEnd() {}
   inherit(FrontEnd, Programmer);
   inherit(BackEnd, Programmer);
   FrontEnd.prototype.lang = ["HTML", "CSS", "Javascript"];
   FrontEnd.prototype.myName = "前端";
   BackEnd.prototype.lang = ["Node", "Java", "SQL"];
   BackEnd.prototype.myName = "后端";
   return {
     FrontEnd: FrontEnd,
     BackEnd: BackEnd,
   };
 })();
 let frontEnd = new initProgrammer.FrontEnd();
 let backEnd = new initProgrammer.BackEnd();
 frontEnd.say();

课后作业

 // 打印一个参数值以内能被3或5或7整除的数
 // 打印斐波那契数列的第N位
 
 // 协同开发不等于插件开发不要用立即执行函数来做
 // 自己单独新建一个作用域 在自己的作用域里写
 window.onload = function () {
   init();
 };
 function init() {
   console.log(initFb(10));
   console.log(initDiv(100));
 }
 let initFb = (function () {
   function fb(n) {
     if (n <= 0) {
       return 0;
     }
     if (n <= 2) {
       return 1;
     }
     return fb(n - 1) + fb(n - 2);
   }
   return fb;
 })();
 let initDiv = (function () {
   function div(n) {
     let arr = [];
     for (let i = 0; i <= n; i++) {
       if (i % 3 === 0 || i % 5 === 0 || i % 7 === 0) {
         arr.push(i);
       }
       return arr;
     }
   }
   return div;
 })();