I'm reading a book called JavaScript Web Applications. In first chapter, it introduces an implementation of class library. Here's an intermediate version:
var Class = function () {
var klass = function () {
this.init.apply(this, arguments);
}
klass.prototype.init = function (args) {};
// Adding class properties
klass.extend = function (obj) {
var extended = obj.extended;
for (var i in obj) {
klass[i] = obj[i];
}
if (extended) extended(klass);
};
// Adding instance propertied
klass.include = function (obj) {
var included = obj.included;
for (var i in obj) {
klass.prototype[i] = obj[i];
}
if (included) include(klass)
};
return klass;
}
Then it can be used like this:
var Person = new Class;
Person.extend({
find: function (id) { /* ... */ }
});
var person = Person.find(1);
var Person = new Class;
Person.include({
save: function () { /* ... */ }
});
var person = new Person;
person.save();
I modified it to that it support non-shared instance properties, and here's my version:
var Class = function (properties) {
var klass = function () {
this.init.apply(this, arguments);
}
klass.prototype.init = function (args) {
var self = this;
if (properties instanceof Array && typeof args === 'object') {
properties.forEach(function (p) {
if (typeof args[p] !== 'undefined') {
self[p] = args[p];
}
});
}
};
// extend and include
return klass;
}
So it can be used like this:
var Person = new Class(['name', 'age'];
var person = new Person({ name: 'bob', age: '30' });
Is my approach ok?
I also wonder that why Person.name
was ""
in my approach? I expected it to be undefined
.
1 Answer 1
There is nothing fundamentally wrong about your class strategy, it is a matter of personal style really. The only suggestion I would have is to add Object.prototype.hasOwnProperty guards in the for-in loops, to avoid extending your classes with bogus properties if someone adds things to Object.prototype.
for (var i in obj) {
if(Object.prototype.hasOwnProperty.call(obj, i)){
// ...
}
}
As for the name === ''
thing, its just a coincidence since Javascript functions (and therefore your class) always have this property defined:
(function(){}).name // ""
(function foo(){}).name // "foo"
Some other properties such as "prototype" or "length" should also always be defined and there is nothing you can do about them.