0 Comments

给“类”库添加方法

发布于:2014-03-31  |   作者:广州网站建设  |   已聚集:人围观

给“类”库添加方法

现在,我们的“类”库(class library)译注1 包含了生成一个实例并初始化这个实例的功能,给类添加属性和给构造函数添加属性是一样的。

直接给类设置属性和设置其静态成员是等价的:


  1. var Person = new Class;  
  2. // 直接给类添加静态方法  
  3. Person.find = function(id){ /* ... */ };  
  4. // 这样我们可以直接调用它们  
  5. var person = Person.find(1);  
  6.  
  7. 给类的原型设置的属性在类的实例中也是可用的:  
  8.  
  9. var Person = new Class;  
  10. // 在原型中定义函数  
  11. Person.prototype.save = function(){ /* ... */ };  
  12. // 这样就可以在实例中调用它们  
  13. var person = new Person;  
  14. person.save(); 

广州网站建设,广州网站设计,广州网站制作,网站建设,网站设计,广州网站建设公司,广州网站设计公司

但在我看来这种语法有些绕,不切实际且不够简洁,很难一眼就分辨出类的静态属性和实例的属性。因此我们采用另外一种不同的方法来给类添加属性,这里用到了两个函数extend() 和include() :

  1. var Class = function () {  
  2. var klass = function () {  
  3. this.init.apply(this, arguments);  
  4. };  
  5. klass.prototype.init = function () {};  
  6. // 定义 prototype 的别名  
  7. klassklass.fn = klass.prototype;  
  8. // 定义类的别名  
  9. klassklass.fn.parent = klass;  
  10. // 给类添加属性  
  11. klass.extend = function (obj) {  
  12. var extended = obj.extended;  
  13. for (var i in obj) {  
  14. klass[i] = obj[i];  
  15. }  
  16. if (extended) extended(klass)  
  17. };  
  18. // 给实例添加属性  
  19. klass.include = function (obj) {  
  20. var included = obj.included;  
  21. for (var i in obj) {  
  22. klass.fn[i] = obj[i];  
  23. }  
  24. if (included) included(klass)  
  25. };  
  26. return klass;  
  27. }; 

 

这段代码是“类”库的增强版,我们使用extend() 函数来生成一个类,这个函数的参数是一个对象。通过迭代将对象的属性直接复制到类上:

  1. var Person = new Class;  
  2. Person.extend({  
  3. find: function(id) { /* ... */ },  
  4. exists: functions(id) { /* ... */ }  
  5. });  
  6. var person = Person.find(1); 

 

include() 函数的工作原理也是一样的,只不过不是将属性复制至类中,而是复制至类的原型中。换句话说,这里的属性是类实例的属性,而不是类的静态属性。

  1. var Person = new Class;  
  2. Person.include({  
  3. save: function(id) { /* ... */ },  
  4. destroy: functions(id) { /* ... */ }  
  5. });  
  6. var person = new Person;  
  7. person.save(); 

 

同样地,这里的实现支持extended 和included 回调。将属性传入对象后就会触发这两个回调:

  1. Person.extend({  
  2. extended: function(klass) {  
  3. console.log(klass, " was extended!");  
  4. }  
  5. }); 

广州网站建设,广州网站设计,广州网站制作,网站建设,网站设计,广州网站建设公司,广州网站设计公司

如果你基于Ruby 实现过类,会感觉它的写法与此很相近。这种写法之美在于它已经可以支持模块了。模块是可重用的代码段,用这种方法可以实现各种继承,用来在类之间共享通用的属性。

  1. var ORMModule = {  
  2. save: function(){  
  3. // 共享的函数  
  4. }  
  5. };  
  6. var Person = new Class;  
  7. var Asset = new Class;  
  8. Person.include(ORMModule);  
  9. Asset.include(ORMModule); 
标签:
飞机