0

For the longest time i have been doing JavaScript classes by doing the following

function MyClass(){
    this.v1;
    this.foo = function(){
        return true;
    }
};

Then i found TypeScript and it looks like it compile its Classes down to

var MyClass = (function () {
    function MyClass(message) {
        this.v1 = message;
    }
    MyClass.prototype.foo = function () {
        return "Hello, " + this.v1;
    };
    return MyClass;
})();

Another Method i have found a lot on the web is

var MyClass = {
    v1:1,
    foo: function(){
       return true;
    }
};

This looks ugly to me but maybe i'm missing something beneficial with this method, as it looks to be the way most people on the web do objects in javaScript.

The first method i'm able to do inharitance from a function i made.

Function.prototype.extends = function(parent){
    this.prototype = new parent();
    this.prototype.constructor = this;
};

I have also seen many other methods on making classes in JavaScript. I would like to know if my method is wrong or if there is a best practice method in doing OOP. All of my projects I have done use the first example. You can see on https://github.com/Patrick-W-McMahon now that I see what JavaScript compilers are doing i'm starting to question my methods. I would like to know what other JavaScript programmers advise is the best method and if there is a difference between the methods. I came from a C++/Java background and as such I write my JavaScript to match my background.

7
  • 1
    there are a million different ways to do "OOP" in js; all have minor advantages and disadvantages, but seldom would those diffs stack up to make something "right" or "wrong". your code is probably more like what Brendan had in mind than typescript's version. Commented Jul 28, 2014 at 19:52
  • possible duplicate of Why does TypeScript mix the module and prototype pattern? Commented Jul 28, 2014 at 20:05
  • Both should work, but using prototype is more standard. Commented Jul 28, 2014 at 20:13
  • with first example you can't achieve inheritance or polymorphism. for example all objects created by new(MyClass) would be inhereted from object and nothing else. Commented Jul 28, 2014 at 20:14
  • would it be different to have this.foo() vs this.prototype.foo() Commented Jul 28, 2014 at 21:03

3 Answers 3

1

What you read here is called the power constructor, more about it here:

Douglas Crockford about Inheritance


As a multi-paradigm language JavaScript lends itself very well to these different considerations. The truth is, it molds around your brain the way you can conceive it.

In other words, if you can reason about your structure in one way, than use it that way.

If you, on the other hand, want to be completely "free" of your own constraints, then you should abandon reasoning in classes altogether and embrace prototypal inheritance without any thing that resembles a class at all. Duck typing is then a natural consequence and in the extreme you'd use closures all over the place.

What I often do is this:

function myItemBuilder(p1)
{
  var s0, p0 = 0;

  // s0 is a shared private property (much like static in classes)
  // p0 is a shared private property but will be factorized (rendered non-shared)
  // p1 is a private instance property

  return (function (p0) { // factorize p0 if necessary

    return {
      publicProperty : 3,
      method1 : function (arg1) {
        // code here (may use publicProperty, arg1, s0, p0 (factorized) and p1)
      },
      method2 : function (arg2) {
        // code here (may use publicProperty, arg2, s0, p0 (factorized) and p1)
      }
    };
  }(p0++)); // on each invocation p0 will be different and method1/method2 will not interfere across invocations (while s0 is shared across invocations)
}

EDIT: The internal closure is only required if you need to factorize p0 (i.e. have separate, independent values for p0 on each invocation). Of course, if you don't need p0 factorized omit the internal closure.

The above example is intentionally more complex than required to illustrate various interesting cases.

Invoking this method like myItemBuilder("hello") builds a new item that has those specific features but there really is no class construct per se.

This is an especially powerful way of getting instances when you want to abandon classical inheritance. For example in C++ you can inherit from more than one class, which is called a mix-in. In Java and C# you only have single-inheritance but interfaces come to your help.

Here, what I've shown above, is the assembly line metaphor which can assemble components into an instance, with the result that there is no concrete (1) difference between class, interface and mix-in. They are all just instances that have features you can reflect upon through meta-programming (duck typing, reflection/inspection). There still is a logical (2) difference in that: (1) concrete instances behave the same independently of the way they come to being but (2) logically an interface is a contract while an instance is an implementation.

If you really understand SOLID and the Assembly Line Metaphor all of this makes sense. Otherwise I beg your pardon for this long answer :)

ADDED:

With this approach you can't check types, but you don't need to because duck typing allows you to find the method you need without having to look at a class or interface contract. This is similar to having each method in a separate single-method interface.

Sign up to request clarification or add additional context in comments.

9 Comments

Thinking of Objects like this is going to take some time. I will be reviewing this post to see if i fully grasp it. Is this much like java factory?
Concrete Factory and Abstract Factory are creational GoF patterns. I guess a java factory is an implementation of one of those two. The Assembly Line Metaphor is very similar, but it is not just a pattern, it is part of the prototypal inheritance paradigm. If all of this does not make sense don't be afraid, just use JS the way you know it, because the most important thing is that you understand and are able to maintain your own code. If you don't know what you're doing, nobody does :)
what is with the }(p1)); at the end of the function doing? the function has (p1) at the beginning. but i don't know what the one at the end is doing.
It invokes the just-defined function. The true name is Closure <- click this. An example is this: function (x) { /*do smthg*/}(3);. This invokes the anonymous function passing 3 for the argument x. As it is anonymous, there's no way you can invoke it anywhere else.
so its much like java's way of doing foo(x=3){/*do smthg */} would this be a correct assumption?
|
0

This is explained here

http://www.2ality.com/2011/06/coffeescript-classes.html

A normal JavaScript class definition, wrapped in an IIFE [3]. There is no benefit for using an IIFE here, apart from having a single assignment (which would matter in an object literal, but doesn’t here).

Comments

0

its a matter of personal preference. Using this method

var MyClass = {
    v1:1,
    foo: function(){
       return true;
    }
};

results in fewer characters and thus smaller JS files so it is the method I usually go with but there is no wrong or right way. Btw. since you commented about this sort of object construction to be ugly you may want to stick with what you are used to. However if you are feeling adventurous check out this project.

It makes oop in javascript quick and painless and MUCH less ugly. Plus it supports multiple inheritance correctly.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.