2011-03-02 75 views
4

我正在用JavaScript編寫一個使用ExtJS的應用程序。減少JavaScript應用程序中構建/使用OOP框架的複雜性的最佳方法是?

當我添加更多的功能,我發現,我想功能封裝成相互繼承的類。來自C#和PHP,我發現JavaScript中面向對象的範例有很大的不同,並沒有真正看到它提供了我需要做的事情。

因此,我正在通過DailyJS Let's Build a Framework教程開展工作,該教程似乎是一種非常有組織的方式,可以將JavaScript轉化爲更多具有類,繼承等的面嚮對象語言。從我的角度來看,這就是我需要的,但我覺得奇怪的是,我自己在JavaScript之上構建所有這些基本功能,只是爲了能夠像PHP或C#一樣使用該語言,即構建一個類層次結構,然後使用它實例化對象。

對於我手頭的任務(通過抽象來降低複雜性),在JavaScript的正確方法之上構建一個像這樣的OOP框架,或者應該以另一種方式使用JavaScript,或者使用已經存在的框架?

下面是此框架如何建立和繼承類的一些例子。

HTML:

<!DOCTYPE html> 
<html> 
    <body> 
    <meta http-equiv="Content-Type" content="text/html; charset: utf-8"> 
    <script type="text/javascript" src="js/dp.core.js"></script> 
    <script type="text/javascript" src="js/dp.oo.js"></script> 
    <script type="text/javascript"> 


     //core 
     document.write('<p>' + dp.VERSION + '</p>'); 

     //define and use class 
     var Layout = dp.Class({ 
      initialize: function(idCode, name) { 
       this.idCode = idCode; 
       this.name = name; 
      }, 
      showChildren: function() { 
       return '(show children)'; 
      }, 
      toString: function() { 
       return 'idCode=' + this.idCode + ', name=' + this.name; 
      } 
     }); 
     var layout = new Layout('layout', 'Layout'); 
     document.write('<p>' + layout.showChildren() + '</p>'); 
     document.write('<p>' + layout + '</p>'); 

     //define and use inheriting class 
     var OrderApprovalLayout = dp.Class(Layout, { 
      initialize: function() { 
       this.$super('initialize', arguments); 
      }, 
      toString: function() { 
       return 'OrderApprovalLayout: ' + this.$super('toString'); 
      } 
     }); 
     var orderApprovalLayout = new OrderApprovalLayout('orderApprovalLayout', 'Order Approval Layout'); 
     document.write('<p>' + orderApprovalLayout + '</p>'); 

    </script> 
</body> 
</html> 

的JavaScript:

dp.Class = function() { 
    return dp.oo.create.apply(this, arguments); 
} 

dp.oo = { 
    create: function() { 
    var methods = null, 
     parent = undefined, 
     klass = function() { 
      this.$super = function(method, args) { return dp.oo.$super(this.$parent, this, method, args); }; 
      this.initialize.apply(this, arguments); 
     }; 

    if (typeof arguments[0] === 'function') { 
     parent = arguments[0]; 
     methods = arguments[1]; 
    } else { 
     methods = arguments[0]; 
    } 

    if (typeof parent !== 'undefined') { 
     dp.oo.extend(klass.prototype, parent.prototype); 
     klass.prototype.$parent = parent.prototype; 
    } 

    dp.oo.mixin(klass, methods); 
    dp.oo.extend(klass.prototype, methods); 
    klass.prototype.constructor = klass; 

    if (!klass.prototype.initialize) 
     klass.prototype.initialize = function(){}; 

    return klass; 
    }, 

    mixin: function(klass, methods) { 
    if (typeof methods.include !== 'undefined') { 
     if (typeof methods.include === 'function') { 
     dp.oo.extend(klass.prototype, methods.include.prototype); 
     } else { 
     for (var i = 0; i < methods.include.length; i++) { 
      dp.oo.extend(klass.prototype, methods.include[i].prototype); 
     } 
     } 
    } 
    }, 

    extend: function(destination, source) { 
    for (var property in source) 
     destination[property] = source[property]; 
    return destination; 
    }, 

    $super: function(parentClass, instance, method, args) { 
    return parentClass[method].apply(instance, args); 
    } 
}; 
+4

避免基於模擬類繼承。改用對象組合。 – Raynos 2011-03-02 13:28:42

+0

你有沒有考慮過看另一個圖書館。我知道YUI和JQuery使類繼承非常簡單。我已經在YUI中構建了一個可重用的JavaScript小部件庫,甚至使用它們的加載器,它工作得非常好。我能夠將這些完全相同的開發實踐應用於此JavaScript庫,就像我使用服務器端代碼一樣。 – Zoidberg 2011-03-02 13:30:14

+4

試圖強制JavaScript像Java或C#一樣行爲通常會流淚。 – Pointy 2011-03-02 13:34:25

回答

1

我會建議對象組合,並使用你的JavaScript功能更強大的方法替代。

僅支持Object構造函數。

例如

function Layout(pr_id, pr_name) { 
    var name = pr_name; 
    var id = pr_id; 

    this.showChildren = function() { 
     return "(showChildren)"; 
    }; 

    this.toString = function() { 
     return "name : " + name + " id : " + id; 
    }; 
} 

function OrderApprovalLayout(id, name) { 
    var layout = new Layout(id, name); 
    // bind the `this` reference inside `layout` to `layout` 
    _.bindAll(layout); 
    // extend `this` with all the `layout` methods 
    _.extend(this, layout); 
    // overwrite `Layout.toString` 
    this.toString = function() { 
     return "OrderApprovalLayout: " + layout.toString(); 
    }; 
} 

這依賴於underscore_.bindAll_.extend

相關問題