`
qyzone
  • 浏览: 5760 次
社区版块
存档分类
最新评论

了解JavaScript设计模式需要掌握的必要知识

阅读更多
作者: hezi


了解JavaScript设计模式需要掌握的必要知识:
1 闭包
  闭包最常用的方式就是返回一个内联函数(何为内联函数?就是在函数内部声明的函数);
  在JavaScript中有作用域和执行环境的问题,在函数内部的变量在函数外部是无法访问的,在函数内部却可以得到全局变量。由于种种原因,我们有时候需要得到函数内部的变量,可是用常规方法是得不到的,这时我们就可以创建一个闭包,用来在外部访问这个变量。
  闭包的用途 主要就是上一点提到的读取函数内部变量,还有一个作用就是可以使这些变量一直保存在内存中。
  使用闭包要注意,由于变量被保存在内存中,所以会对内存造成消耗,所以不能滥用闭包。解决方法是 在退出函数之前,将不使用的局部变量全部删除。举例如下:
  function f(){
     var i = 999;
     function f1(){
      alert(i+=1);
      }
      return f1;
  }
  var result = f();
    result(); // 1000
    result(); // 1001
    result(); // 1002
2 封装:
  
   通过将一个方法或者属性声明为私用的,可以让对象的实现细节对其他对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束,这样可以是代码更可靠,更易于调试。封装是面向对象的设计的基石。
    尽管JavaScript是一门面向对象的语言,可它并不具备将成员声明为公用或私用的任何内部机制,所以我们只能自己想办法实现这种特性。下面还是通过一套完整的代码去分析,介绍什么是私有属性和方法,什么是特权属性和方法,什么是公有属性和方法,什么是公有静态属性和方法。举例:
  
  3  私有属性和方法:
   函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量。
  
  
  4 特权属性和方法:

   创建属性和方法时使用的this关键字,因为这些方法定义在构造器的作用域中,所以它们可以访问到私有属性和方法;只有那些需要直接访问私有成员的方法才应该被设计为特权方法。
  
  
   5  共有属性和方法:
  直接链在prototype上的属性和方法,不可以访问构造器内的私有成员,可以访问特权成员,子类会继承所有的共有方法。
  
   6 共有静态属性和方法:
  最好的理解方式就是把它想象成一个命名空间,实际上相当于把构造器作为命名空间来使用。
     /* -- 封装 -- */
     var _packaging =function(){
     //私有属性和方法
     var name ='Darren';
     var method1 =function(){
      //...
     }
     //特权属性和方法
     this.title ='JavaScript Design Patterns' ;
     this.getName =function(){
      return name;
     }
     }
     //共有静态属性和方法
    _packaging._name ='Darren code';
     _packaging.alertName =function(){
     alert(_packaging._name);
     }
     //共有属性和方法
     _packaging.prototype = {
     init:function(){
     //...
     }
    }
  7 继承 :分为类式继承和原型式继承 。
  /* -- 类式继承 -- */
   2   //先声明一个超类
   3   function Person(name){
   4     this.name = name;
   5   }
   6   //给这个超类的原型对象上添加方法 getName
   7   Person.prototype.getName =function(){
   8   returnthis.name;
   9   }
  10   //实例化这个超类
  11   var a =new Person('Darren1')
  12   alert(a.getName());
  13   //再声明类
  14   function Programmer(name,sex){
  15   //这个类中要调用超类Person的构造函数,并将参数name传给它
  16   Person.call(this,name);
  17   this.sex = sex;
  18   }
  19   //这个子类的原型对象等于超类的实例
  20   Programmer.prototype =new Person();
  21   //因为子类的原型对象等于超类的实例,所以prototype.constructor这个方法也等于超类构造函数,你可以自己测试一下,如果没这一步,alert(Programmer.prototype.constructor),这个是Person超类的引用,所以要从新赋值为自己本身
  22   Programmer.prototype.constructor = Programmer;
  23   //子类本身添加了getSex 方法
  24   Programmer.prototype.getSex =function(){
  25   returnthis.sex;
  26   }
  27   //实例化这个子类
  28   var _m =new Programmer('Darren2','male');
  29   //自身的方法
  30   alert(_m.getSex());
  31   //继承超类的方法
  32   alert(_m.getName());
  
  
   /* -- 原型式继承 -- */
   2   //clone()函数用来创建新的类Person对象
   3   var clone =function(obj){
   4 var _f =function(){};
   5   //这句是原型式继承最核心的地方,函数的原型对象为对象字面量
   6   _f.prototype = obj;
   7   returnnew _f;
   8   }
   9   //先声明一个对象字面量
  10   var Person = {
  11   name:'Darren',
  12   getName:function(){
  13   returnthis.name;
  14   }
  15   }
  16   //不需要定义一个Person的子类,只要执行一次克隆即可
  17   var Programmer = clone(Person);
  18   //可以直接获得Person提供的默认值,也可以添加或者修改属性和方法
  19   alert(Programmer.getName())
  20   Programmer.name ='Darren2'
  21   alert(Programmer.getName())
  22
  23   //声明子类,执行一次克隆即可
  24   var Someone = clone(Programmer);
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics