zoukankan      html  css  js  c++  java
  • JavaScript 设计模式系列:基础知识

       基础知识

      约定:在JavaScript业界,如果变量和方法是使用下划线,则表示该变量和方法是私有方法,只允许内部调用,第三方不应该去调用。

      1>>双重“非”操作返回的是布尔型的数据:

        var bool = !!num;

      2>>函数是一等对象:

      1:匿名函数

        

    1  function(){...}

      2:立即调用的匿名函数:

    1 (function(){//立即调用的匿名函数
    2      var foo = 10;
    3      var bar = 2;
    4      alert(foo * bar);
    5 })();

      3:从外部传值的立即调用的匿名函数:

    1 (function(foo,bar){
    2      alret(foo * bar);
    3 }(10,2);

      4:将立即调用的匿名函数的返回值赋给一个变量:

    1 var baz = (function(foo,bar){
    2     return foo * bar;
    3 })(10,2)

       5:创建闭包:

    1 var baz;
    2 (function(){
    3      var foo = 10;
    4      var bar = 2;
    5      baz = function(){
    6            return foo * bar;
    7      };
    8 })();
    9 baz();

    闭包:

      1. 最常用的方法是在函数内部返回一个函数,这个返回的函数可以访问内部变量。

          2. 主要就是上一点提到的读取函数内部变量,还有一个作用就是可以使这些变量一直保存在内存中。

    如:变量n一直保存在内存中,每执行一次函数,就继续+1。

     1 function  f(){
     2      var n =100;
     3      function f1(){
     4       alert(n+=1);
     5   }
     6 return f1;
     7 }
     8 var result = f();
     9 result();//101
    10 result();//102
    11 result();//103

    3>>封装:

    继承:有两种继承方式

    原型继承:通过将对象赋给函数的原型,然后将这个函数返回给一个对象。这样这个初始的对象就获得了开始时的那个对象的属性和方法,实现了继承。

    //clone用来创建新的类Person对象
    var clone = function(obj){
      var f = function(){};
      //**函数的原型对象是对象字面量,即函数的原型里有obj对象的属性和方法
      f.prototype = obj;
      return f;
    }
    //定义的对象字面量
    var Person = {
      name:'free',
      getName:function(){
        return this.name;
      }
    }
    //创建子类 ,创建的继承对象可以调用父类的方法
    var Programmer = clone(Person);
    //继续继承
    var Someone = clone(Programer);

    类式继承:  1.构建子类构造函数,同时将需要处理的参数传给父类构造函数。

           2.将父类的实例赋给子类的原型。

           3.修正子类的constructor属性。constructor属性指向构造函数属性,这里是 Person,修正为Programmer

     1 //构造函数,相当于超类
     2 function Person(name){
     3       this.name = name;
     4 }
     5 //原型上加方法
     6 Person.prototype.getName = function(){
     7       return this.name;
     8 }
     9 //实例化这个超类
    10 var a = new Person('free');
    11 alert(a.getName());//free
    12 
    13 //再声明类,子类  
    14 function Programmer(name,sex){
    15     //这个类要调用Person的构造函数,并将参数传进去
    16     Person.call(this,name);
    17     this.sex = sex;
    18 }
    19 //子类的原型对象等于超类的实例
    20 Programmer.prototype = new Person();
    21 //修正constructor属性,最终需要指向Programmer。
    22 Programmer.prototype.constructor = Programmer;
    23 
    24 Programmer.prototype.getSex = function(){
    25      return this.sex;
    26 }
    27 
    28 var test = new Programmer('free','male');
    29 alert(m.getSex());//male
    30 alert(m.getName());//free

     4>>接口:提供了一种用以说明一个对象应该具有哪些方法的手段。但并不规定这些方法应该如何实现。

      既定的一批接口具有自我描述性,并能促进代码重用。接口可以告诉我们一个类实现了哪些方法,从而帮助其使用这个类。有利于测试和调试!可以很快发现类型错误。

      实现一:用注释描述接口:在实现接口的方法时加入注释,没有验证!

     1 interface Composite{//接口一
     2   function add(child);
     3   function remove(child);
     4   function getChild(index);
     5 }
     6 
     7 interface FormItem{//接口二
     8   function svae();
     9 }
    10 //创建类
    11 var CompositeForm = function(id,method,action){
    12   ...
    13 };
    14 //实现接口中的方法
    15 CompositeForm .prototype.add = function(child){
    16   ...
    17 };
    18 
    19 CompositeForm .prototype.remove= function(child){
    20   ...
    21 };
    22 
    23 CompositeForm .prototype.getChild= function(index){
    24     ...
    25 };
    26 
    27 CompositeForm .prototype.save= function(){
    28   ...
    29 };

      实现二:用属性检查模仿接口:所有的类都明确声明自己实现了那些接口,通过检查一个属性的值某个类自称实现了的接口。

     1  interface Composite{//接口一
     2    function add(child);
     3    function remove(child);
     4    function getChild(index);
     5  }
     6  
     7  interface FormItem{//接口二
     8    function svae();
     9  }
    10 
    11 //声明类 实现了的接口
    12 var CompositeForm = function(id,method,action){
    13        this.implementsInterfaces = ['Composite','FormItem'];
    14 };
    15 
    16 function addForm(formInstance){
    17        if(!implements(formInstance,'Composite','FormItem'){
    18                throw new Error("wrong!!");
    19         }
    20 }
    21 
    22 function implements(object){
    23        for(var i =1,i<arguments.length;i++){
    24               var interfaceName = arguments[i];
    25               var interfaceFound = false;
    26               for(var j=0;j<object.implementsInterfaces.length;j++ ){
    27           if(object.implementsInterfaces[j] == interfaceName){
    28             interfaceFound = true;
    29                      break;
    30           }                      
    31 
    32          }
    33         if(!interfaceFound){
    34           return false;
    35         }
    36        }
    37     return true;
    38 }

      通过调用addForm传入需要检查的对象,然后调用implements方法检查对象是否实现接口,只检查名称,没有检查对应的方法。

       

      实现三:鸭式辩型模仿接口:类是否声明支持那些接口并不重要,只要它具有这些接口中的方法就行。

     1 //接口一
     2 var Composite = new Interface('Composite',['add','remove','getChild']);
     3 //接口二
     4 var FormItem = new Interface('FormItem',['svae']);
     5 
     6 //实现接口的类
     7 var CompositeForm = function(id,method,action){
     8       ...
     9 };
    10 //检验接口的方法
    11 function addForm(formInstance){
    12        ensureImplements(formInstance,Composite,FormItem);
    13        ...
    14 }

    首先定义一个Interface类,然后在Interface类中定义ensureImplements方法!

    Interface()类用于生成接口

     1 //定义接口
     2 var Interface = function(name,methods){
     3   if(arguments.length != 2){//参数个数必须要大于两个
     4     throw new Error("wrong1!!");
     5   }
     6   this.name = name;
     7   this.methods = [];
     8   for(var i = 0,len = methods.length;i<len;i++){
     9     if(typeof methods[i] !== 'string'){//方法不是字符串,报错
    10       throw new Error("wrong2!!");
    11       }
    12     this.methods.push(methods[i]);//将方法压入到this.methods数组中
    13   }
    14 };

      ensureImplements方法用于确认方法被实现!

     1 Interface.ensureImplements = function(object){
     2   if(arguments.length <2){//检查参数个数
     3     throw new Error("wrong3");
     4   }
     5   //检查参数个数
     6   for(var i =1,len = arguments.length;i<len;i++){
     7     var interface = arguments[i];
     8     if(interface.constructor !== Interface){
     9       throw new Error("wrong4");
    10     }
    11     for(var j = 0,methodsLen = interface.methods.length;j<methodsLen){
    12       var method = interface.methods[j];
    13       //检查方法类型和方法是否存在
    14       if(!object[method] || typeof object[method] !== 'function'){
    15         throw new Error("wrong5");
    16       }
    17     }
    18   }
    19 }

     

     

  • 相关阅读:
    L1-049 天梯赛座位分配​​​​​​​
    L1-046 整除光棍 大数除法
    天梯赛 L1-043 阅览室
    Hdu 1022 Train Problem I 栈
    蓝桥杯 历届试题 格子刷油漆  (动态规划)
    第九届蓝桥杯省赛真题 日志统计
    2018年第九届蓝桥杯第7题 螺旋折线
    2018年第九届蓝桥杯省赛 递增三元组
    蓝桥杯 历届试题 高僧斗法  (尼姆博弈)
    K-th Number
  • 原文地址:https://www.cnblogs.com/colorstory/p/2588068.html
Copyright © 2011-2022 走看看