开发者

Is the best approach to reduce complexity in a JavaScript application to build/use an OOP framework on top?

开发者 https://www.devze.com 2023-02-14 21:03 出处:网络
I am building an application in JavaScript using ExtJS. As I add more functionality to it, I find that I would like to encapsulate functionality intoclasses which inherit from each other. Coming fro

I am building an application in JavaScript using ExtJS.

As I add more functionality to it, I find that I would like to encapsulate functionality into classes which inherit from each other. Coming from C# and PHP, I find the object-oriented paradigms in JavaScript quite different and don't really see that it offers what I need to do this.

Therefore, I am working through the DailyJS Let's Build a Framework tutorial which seems to be a very structured way to turn JavaScript into more of an object-oriented language with classes, inheritance, etc. From my point of view, this is what I need, yet I feel odd having to build all this base functionality by myself on top of JavaScript just to be able to use the language as I would PHP or C#, i.e. build a class hierarchy and then instantiate objects with it.

For my task at hand (reducing complexity through abstraction) is building an OOP-framework like this on top of Javascript the right approach, or should I be using JavaScript in another way, or perhaps using a framework that already exists?

Below are some examples of how this framework builds and inherits classes.

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, {
            ini开发者_运维问答tialize: 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);
  }
};


I would advice an alternative of Object composition and using a more functional approach to your JavaScript.

Stick to Object constructors only.

For example

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();
    };
}

This relies on underscore and _.bindAll and _.extend

0

精彩评论

暂无评论...
验证码 换一张
取 消