Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

OOP in Javascript: Class function to define "classes"

100 views
Skip to first unread message

lzz...@gmail.com

unread,
Nov 17, 2012, 9:25:03 AM11/17/12
to
Hi all,
this is my first post here but i often follow this group.

I' ve recently written a tool that provides a “Class” function in Javascript and i would like to share it: it is intended to be a really light copy of the MooTools’s Class function with basic features, to add a little bit of OOP in Javascript and make the inheritance easier.

Here you can find more about it, examples and sources (it is a post on my blog, i hope it is ok to post it):
http://nerdstuckathome.wordpress.com/2012/11/14/a-class-function-to-define-classes-in-javascript-with-mootools-like-syntax/

Every feedback will be really appreciated!

Thank for read,
Luca

John G Harris

unread,
Nov 18, 2012, 11:55:24 AM11/18/12
to
On Sat, 17 Nov 2012 at 06:25:03, in comp.lang.javascript, wrote:
>Hi all,
>this is my first post here but i often follow this group.
>
>I' ve recently written a tool that provides a “Class” function in
>Javascript and i would like to share it: it is intended to be a really
>light copy of the MooTools’s Class function with basic features, to add
>a little bit of OOP in Javascript and make the inheritance easier.
>
>Here you can find more about it, examples and sources (it is a post on
>my blog, i hope it is ok to post it):
>http://nerdstuckathome.wordpress.com/2012/11/14/a-class-function-to-
>define-classes-in-javascript-with-mootools-like-syntax/

Here are some comments :-


1 "to add a little bit of OOP in Javascript"

OOP is about using objects each of which has its own data and shares the
use of some functions and inherited functions with certain other
objects. Native ECMAScript provides these facilities without any extra
code. ECMAScript is as OOP as Java and C++. Any differences, such as
rigid type checking and textual class-definitions are just icing on top
of the OOP cake.



2 "MooTools syntax compatibility"

Why? You say at the end that your code is for use outside MooTools so
why does it have to be the same?



3 At "Implements Example"

Why Implements? In Java, "implements" and its cousin "interface" are
used to get round the strict typing of objects. In ECMAScript you can do
x.a() without worrying what kind x is just so long as it's an object
and has a callable property named "a".



4 "Properties are NOT searched up on the prototype chain"

Quite right. Sort of. Each object has its own data properties. They
should not be shared by putting them in the prototype chain.

On the other hand, your example seems to be saying that data properties
are added to the prototype chain as well. This is silly.



5 "About function, thay are taken from the prototype chain but not when
a class extends another class:"

ECMAScript engines go to a lot of trouble to make access of functions
held in the prototype chain as efficient as possible, including
inherited functions, then you don't use it! Why, for goodness sake?



6 General

I think it would be better for you to go back to square 0, think
carefully about what you really want to achieve, then devise a scheme to
do it that is as clear and simple as possible for users. You now have
some experience at doing that kind of thing so it might not be so
difficult at the next iteration.


John
--
John Harris

Luca Lazzarini

unread,
Nov 18, 2012, 3:28:56 PM11/18/12
to jgha...@ic4life.net
As first, thank you for asnwer. I think you gave me a smart point of view, anyway i have somethings to answer about what you wrote. I wrote a lots, i am sorry about that!

1
Well, i cannot completly disagree with you: "to add a little bit of OOP in Javascript" are big words!
Anyway, what i meant is about the readibility of the code:

- the Class function introduces in Js keywords like Extends and Implements and a feature like the "parent method": they are keywords / feature borrowed directly from Java (so i am speaking about syntax / looks like).

- when i read a Java class and a JS one i think they could be really close, check this example from a friend of mine:
docs.oracle.com/javase/tutorial/java/concepts/class.html
The thing is: the emphasis of defining objects in Js is on the function:
var Bicycle = function() {
// some code...
}
Bicle.prototype.changeCadence = function(){ /*some code*/ };
Bicle.prototype.changeGear = function(){ /*some code*/ };
// ...other methods...
using the Class function "the emphasis is on the object, that is the prototype" (words i have borrow from the same friend, he was speaking about ES5 Object.create).

- i don't think about Javascript as OOP like Java and C++.
A line from http://helephant.com/2008/09/14/constructor-functions/, because i am not able to explain my thought better:
"(...in JS...) Constructor functions look a lot like classes in other languages but they’re not. In a language like Java or C# a class is synonymous with a data type. It gives you guarantees about what properties and methods the instances of the classes will have."
It is not the same using Js, you can always make changes to an object.
Using the Class function that is still true (i am not a magician) but you cannot change a class property (on its prototype) from an instance of that class (you can in pure Js because of the prototypal chain).

My personal, modest opinion about it is: prototypal chain is amazing but quite confusing for many developers (and for code readibility sometimes?).
Using Class function the data properties on the prototype are unique for every instances and when you want to use the prototypal chain, you can just define an object in pure Js: you can always extend / implement it in Class's class.

2
From my post: "MooTools syntax compatibility (means be allowed to move the code on MooTools or project like moo4q in the future)"
A real example: you are developing with jQuery and you like to use a basic Class tool. Reading the goals of the Class function from my post you are happy with them and you join it. In the future, you realize you want more: an example, a clean way to have private members (my function has a way to define them but it is not so clean; MooTools, instead, has good features about it).
In that case, you will feel free to move your code on a project like moo4q, an alternative with more ambitious goals than my function or you can move your code on MooTools itself!
Of course if you are using any other toolkit / framework you probabily don't want to move the code on MooTools (i am thinking about all the differences you should fix in a lots of areas). Anyway, from what i know, you could use no toolkit / framework so is still true that you can move your code on MooTools itself (well, it is a goal of my function!) !

3
As first, to keep the compatibility with MooTools. That is the most of it, anyway i really like the Implements feature and this is the purpose i see for it:

- when you have a collection (as object) of methods that you often include in your objects, include them in the objects you need by Implements could be more readable then a for...in loop

- when you have a collection of methods you often override in your objects, can be a good idea to keep them just defined (but not implemented) and include them in the objects you need by Implement, then write their implementation: yes, in the end that means copy empty methods on your objects by Implements... Why that makes sens to me? Code readibility (in my post there is an example about Implements and the function DIE and it looks really good to me)

4
The Class function takes an object as input parameter, that object is the prototype of your future class.
If you don't want some data properties on the prototype of your class, you should move their definition inside the constructor (it is the "initialize" function). Anyway, if you want them on the prototype, the Class function makes sure to "break" the prototypal chain.
I will add this in my post.
The real thing i don't like about that is: the Class function clones every data property (on the prototype) for every instance... Expensive, i am making it conditionable.

5
I think you didn't get my point: the Class function OF COURSE USES the prototypal chain for functions!
It is not true only when, extending a class, a function has the same name on sub and super: in that case, a function on the sub, in that case, is a wrapper to the super's function.
Anyway i didn't specify, in the post, it is only about same name functions (i specified it is about Extends): i will add it.




6
Thank you for read! :)

John G Harris

unread,
Nov 19, 2012, 11:07:55 AM11/19/12
to
On Sun, 18 Nov 2012 at 12:28:56, in comp.lang.javascript, Luca Lazzarini
wrote:

<snip>
>3
>As first, to keep the compatibility with MooTools.

If that's your objective then good luck. But it doesn't describe the
instance objects as clearly as a Java or C++ class definition does.


<snip>
>4
>The Class function takes an object as input parameter, that object is
>the prototype of your future class.

It shouldn't be a prototype, or described as one. It should be a
declaration of what must be in each object. E.g A collection of data
property names; a collection of method property names and their
definitions; odds and ends such as super's name.

Incidentally, why "initialise"; why not "construct"?


John
--
John Harris

Luca Lazzarini

unread,
Nov 19, 2012, 12:37:50 PM11/19/12
to jgha...@ic4life.net
>>>>3
>>>>As first, to keep the compatibility with MooTools.
>>If that's your objective then good luck. But it doesn't describe the instance objects as clearly as a Java or C++ class definition does.

It is my objective, only for the basic features provided of my function...! :)
About Implements, i have read more than one post about devs asking how to use it so i think it is considered quite confusing from many sources and i am not saying it is not; i was confused too when i used MooTools for the first times.
Anyway i think Implements has a lots of power. Well, i don't want to convince anyone about that, it is only my opinion and i think every dev probably has a different opinion about it...
I wrote an example about Implements at the end of my answer; i hope i didn't write something stupid or wrong and i hope it could explain my point of view and maybe it could be useful.

>>>>4
>>>>The Class function takes an object as input parameter, that object is
>>>>the prototype of your future class.
>>It shouldn't be a prototype, or described as one. It should be a
>>declaration of what must be in each object. E.g A collection of data
>>property names; a collection of method property names and their
>>definitions; odds and ends such as super's name.

Well, as i wrote, the prototypal chain is "broken" so, in the end, i think the Class's parameter looks like a "declaration of what must be in each object" and we could say "it is"... You know it is the prototype only checking the prototype of your class and i think it is really important to get members on the prototype of the class: thank to that, you can easily inherit your class using prototypal inheritance.

>Incidentally, why "initialise"; why not "construct"?
To keep MooTools compatibility! :)
As i wrote in my post: "(... my function ...) is intended to be a really light copy of the MooTools’s Class function with basic features"


An example about Implements:
----------------------------

Preamble:
You have objects ObjectA and ObjectB; you wrote a Class Reader that reads some data (as text) from a source, process it and return the result.
You want to add the Reader feature on those objects but that feature needs to access the data from those objects; one object has the data stored on its this.text property and the other one on the this.otherText property.
You don't want to change the objects's code... you are using them in so many places yet!
This is a really clean way in which i think you can solve the problem:

var DIE = function() { throw new Error("Method not implemented"); };
var Reader = new Class({
read: function() {
var data = this.getData();
data = this.convert(data);
return data;
},
convert: function(data){
// some operations on data...
return data + ";";
};
getData: function(){
DIE();
}
});

var ObjectA = new Class({
Implements: Reader,
text: "text",
/*some more members if you want...*/
getData: function(){
return this.text;
}
});

var ObjectB = new Class({
Implements: Reader,
otherText: "other text",
/*some more members if you want...*/
getData: function(){
return this.otherText;
}
});

var a = new ObjectA(),
b = new ObjectB();
alert(a.read()); // alert "text"
alert(b.read()); // alert "other text"

Add the "read" feature on objects with potentially completely different members was really clean!
The same in pure Js is:

var Reader = function() {};
Reader.prototype.read = function() {
var data = this.getData();
data = this.convert(data);
return data;
};
Reader.prototype.convert = function(data) {
return data + ";";
};
Reader.prototype.getData = function() {
DIE();
};

var ObjectA = function() {};
ObjectA.prototype.data = "text";
/*some members*/
ObjectA.prototype.getData: function(){
return this.data;
};
for(var fn in Reader) {
ObjectA.prototype[fn] = Reader.prototype[fn];
}

var ObjectB = function() {};
ObjectB.prototype.otherData = "other text";
/*some members*/
ObjectB.prototype.getData: function(){
return this.otherData;
};
for(var fn in Reader) {
ObjectB.prototype[fn] = Reader.prototype[fn];
}

var a = new ObjectA(),
b = new ObjectB();
alert(a.read()); // alert "text"
alert(b.read()); // alert "other text"

You can do the same in Js, no additional code and less operation executed then...
But to me the Implements version is really more readable and that makes the difference for me.

I wrote a lots, sorry about that...
All i wrote is my modest opinion.





Scott Sauyet

unread,
Nov 19, 2012, 10:14:18 PM11/19/12
to
John G Harris wrote:
> Luca Lazzarini  wrote:

>> I've recently written a tool that provides a “Class” function in
>> Javascript and i would like to share it: it is intended to be a really
>> light copy of the MooTools’s Class function with basic features, to add
>> a little bit of OOP in Javascript and make the inheritance easier.
>
>> Here you can find more about it, examples and sources (it is a post on
>> my blog, i hope it is ok to post it):
>> http://nerdstuckathome.wordpress.com/2012/11/14/a-class-function-to-
>> define-classes-in-javascript-with-mootools-like-syntax/

The usual best practices here are to post some reasonable portion
here. A link is fine, but there should also be enough information
inline to give us a good idea of what's under discussion.

I agree with all of John's earlier points, but want to stress this
one:

> I think it would be better for you to go back to square 0, think
> carefully about what you really want to achieve, then devise a scheme to
> do it that is as clear and simple as possible for users. You now have
> some experience at doing that kind of thing so it might not be so
> difficult at the next iteration.

If you treat what you've done so far as an excellent learning
experience, and then come back at the problem with a fresh set of
eyes, you might have a very different approach, and most likely a
significantly better one.

You do need to consider how much of this is even necessary. MooTools
seems to do a great deal to try to make Javascript look more like
traditional Object-Oriented languages such as Java. This necessarily
loses some of the funky flavor that makes Javascript such an
interesting (set of) language(s). And it really gains nothing in
expressive power or overall simplicity. All this really does it make
it *look* as though Javascript is more like a statically typed
language. Unless and until we have some of the sealing/freezing
capabilities of ES5 widely available, none of these attempts to
replicate such type-safe features will actually provide what they
claim to provide. And there is nothing you can do about that. So as
well as reconsidering your technique, you really should think about
whether your basic goal is even sensible here.

It's not that I necessarily think your code is horribly wrong. In
fact, I've only glanced at it. But I'm not sure you are chasing goals
worth pursuing.

Cheers,

-- Scott

John G Harris

unread,
Nov 20, 2012, 9:19:48 AM11/20/12
to
On Mon, 19 Nov 2012 at 09:37:50, in comp.lang.javascript, Luca Lazzarini
wrote:

<snip>
>>>It shouldn't be a prototype, or described as one. It should be a
>>>declaration of what must be in each object. E.g A collection of data
>>>property names; a collection of method property names and their
>>>definitions; odds and ends such as super's name.
>
>Well, as i wrote, the prototypal chain is "broken" so, in the end, i
>think the Class's parameter looks like a "declaration of what must be
>in each object" and we could say "it is"... You know it is the
>prototype only checking the prototype of your class and i think it is
>really important to get members on the prototype of the class: thank to
>that, you can easily inherit your class using prototypal inheritance.

The prototype chain is a linked list that is searched from front to
back, stopping when the desired name is found or when falling off the
end of the list. What could be simpler?

Why "break" this chain?


<snip>
>An example about Implements:
>----------------------------
<snip>

Be aware that this is nothing like "implements" in Java.


John
--
John Harris

Luca Lazzarini

unread,
Nov 20, 2012, 11:21:32 AM11/20/12
to jgha...@ic4life.net
Well, the idea is to break the prototypal chain only to make data properties, defined on the "class", unique. Well, to say it better: i think the idea of MooTools minds about that, is the one i said.
That means that you cannot change the a data property on the prototype of a constructor function from an instance of that function itself!

About Implements, i think you right when you say it is not the same that in Java and Implements can be a confusing name... nothing to say about it. But i think aswell it can be an interesting tool to have and Js doesn't provide this kind of tools natively.

In the end, i think your considerations make sense but from my side, i don't think it is a so wrong to use a tool like Class inside a project.

All in my modest opinion,
Luca

Luca Lazzarini

unread,
Nov 22, 2012, 6:15:57 AM11/22/12
to
S
Sorry for my late answer...
I still have some problems with english, so i hope i have got the most from your answer.
I think my last answer to austincheney, on JSMentors group, explains the goals of the function. i am saying that because i see you are there too.
I wrote about what i see as improvements for the syntax provided by the function Class and my point of view about OOP in Js, using constructors; i see my work as an achievement for the target goals.
What i just wrote is for these your lines:

> All this really does it make
> it *look* as though Javascript is more like a statically typed
> language. Unless and until we have some of the sealing/freezing
> capabilities of ES5 widely available, none of these attempts to
> replicate such type-safe features will actually provide what they
> claim to provide.

I would like to encourage the OOP in Js, by my function, but using the native way provided by Js...
If you think i should, i can paste here my answer from the JSMentor group to share it with who could be insterested here.

Thank you,
Luca
0 new messages