2
\$\begingroup\$

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.

asked Jul 3, 2012 at 6:01
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

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.

answered Jul 3, 2012 at 14:37
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.