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
精彩评论