1

When I switched to the revealing module pattern in Javascript, it was a sigh of relief. No more this, that, exports.func, that.func.bind(that), function() { that.success(); }, etc. In fact, in my modules no more occurrences of 'this' even exist, hence less confusion and more clarity! If only I could also apply the same concept to a class. This would allow me to work within the private scope of the class, and reveal only public functions at the bottom. Here is my attempt to do this, is it even a class? Do you see any problems with this implementation?

var TestClass = function(_a) {
    var a = _a;

    function func() { console.log(a); }

    return {
        func: func
    }
};

var tc1 = new TestClass(1);
var tc2 = new TestClass(2);

tc1.func();     //1
tc2.func();     //2

EDIT: I call it the 'Revealing Class Pattern' (w3core below gave me this idea)

var TestClass = function(_a) {
    var a = _a;

    function func() {
        console.log(a);
    }

    this.func = func;
};

TestClass.prototype.shared = function() {
    console.log(5);
};

var tc1 = new TestClass(1);
var tc2 = new TestClass(2);

tc1.func();     //1
tc2.func();     //2

tc1.shared();   //5
tc2.shared();   //5

tc1.constructor;           //function TestClass()
tc1 instanceof TestClass;  //true

This method seems to fix the 'instanceof' problem as mentioned in the comments. Also, the constructor is now set to the function as well.

wayofthefuture
  • 4,222
  • 6
  • 26
  • 45
  • *Do you see any problems with this implementation* - `func` has to be created everytime the constructor is called. – thefourtheye Sep 06 '15 at 23:27
  • Right, I have no problem with func being recreated. For specific cases where performance will matter I would use the prototype method, but I personally think it's more important to have a clear, easy to read, and easy to understand class that works under all circumstances. – wayofthefuture Sep 06 '15 at 23:29
  • The object won't have a `.constructor` property and won't work with `instanceof TestClass` and when debugging, it won't show you what type of object it is. – jfriend00 Sep 06 '15 at 23:29
  • @jfriend00 that doesn't seem like much of a sacrifice, considering I can now have a class that's completely encapsulated. – wayofthefuture Sep 06 '15 at 23:31
  • I'm not arguing one way or the other - there are others advocating a variant of this style. You asked what the issues are, so I enumerated a few. I find the debugging issue relevant and occasionally the `instanceof` issue. If you're having trouble getting `this` correct with traditional declarations, then perhaps you just need to learn how it actually works in Javascript so you can use it properly. – jfriend00 Sep 06 '15 at 23:38
  • @jfriend00 roger I need to learn more about 'this'.... I have tried over and over again but always seem to get lost when actually sitting down and writing code :( – wayofthefuture Sep 06 '15 at 23:39
  • How do you derive from this object? It doesn't appear you can call the parent constructor on an existing object. – jfriend00 Sep 06 '15 at 23:39
  • 2
    How do you Inherit from this (an important tenant of object oriented design)? – jfriend00 Sep 06 '15 at 23:40
  • @jfriend00 I don't, ever. 80% of the application is Modules. I really just can't find much use for classes in our application. – wayofthefuture Sep 06 '15 at 23:41
  • 1
    Then, why are you asking a question about implementing Javascript classes? Your question is now in a weird state where you ask how appropriate this is for classes, but when we point out something it can't do that is central to object oriented design, you say that doesn't matter to you. I guess we don't know what you're really asking. It sounds like you just want to defend your design rather than actually understand the potential disadvantages. IMO, you won't get very far in writing really good Javascript code if you never inherit anything. – jfriend00 Sep 06 '15 at 23:45
  • @jfriend00 Roger, those are all good points. I'm trying to defend because I can't stand putting 'this' all over the page. It's complex and I'd rather just remove the risk of getting it wrong. Misunderstanding 'this' is extremely widespread I am among millions, and definitely not one of the 'good parts' of javascript that I'm looking for. Removing 'this' confusion allows me to write code, that in short, just works. And that's all I want, code that just works, and, is easy to read. But yes I want to defend it because I really want to use it! :P – wayofthefuture Sep 06 '15 at 23:51
  • Then, you're in the wrong place. Because your question is really "can I use this style for what I do", but you've not described at all what you do. So, we have no idea how to response. It's not a general purpose style at all because it doesn't do inheritance. See [this answer](http://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676) for a discussion of `this`. – jfriend00 Sep 06 '15 at 23:53
  • The workings of `this` are really not that complicated and have been explained in countless Stackoverflow answers, blog posts, books, and videos. You really can't be an effective JavaScript developer without having a grasp of it, as just about every library API makes use of basic JavaScript function behaviors somehow or other. – Pointy Sep 06 '15 at 23:54
  • @jfriend00 Do you know if Douglas Crockford's private member class method allows inheritance? http://javascript.crockford.com/private.html – wayofthefuture Sep 06 '15 at 23:55
  • @Pointy But that doesn't change the fact that having thousands of occurrences of 'this' all throughout the code makes it so much harder to read and understand. And you have to remember to bind the 'this' context when using functions that execute in a difference scope, like ajax success and settimeout. – wayofthefuture Sep 06 '15 at 23:57
  • 1
    Yes, that Crockford scheme does allow inheritance. FYI, he has several new schemes out too as that document is pretty old. – jfriend00 Sep 06 '15 at 23:57
  • @jfriend00 Do you have a link to those schemes? Thanks – wayofthefuture Sep 06 '15 at 23:58
  • No. I do not have them handy. I've watched a video that he describes them in. He's well referenced so I'm sure you can find them on Google. I'm not a particular fan. I read to learn and study, but don't always agree with his strong opinions. – jfriend00 Sep 06 '15 at 23:59
  • @Pointy "The workings of this are really not that complicated".... if that were true then there wouldn't be "countless" questions, blog posts, books, videos, over and over... In fact, it's VERY complicated. http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work?lq=1 – wayofthefuture Sep 07 '15 at 00:02
  • You can find some programming techniques that will avoid some uses of `this`, but you will still be severely limiting what you can do with Javascript if you steadfastly refuse to learn how it works and when it would be a good tool to solve a problem. It's a tool that has many valid and useful ways in which it can be used. Refusing the learn that tool is not helping you advance your understanding of Javascript programming. You would fairly quickly fail many interviews for a job writing Javascript working on other people's code too or with other people. – jfriend00 Sep 07 '15 at 00:05
  • @Dude2TheN well, if that's "VERY complicated" then there are a lot of other things for which I wouldn't know what superlatives to use. There are only two basic ways that `this` is determined in a given function invocation, and then a couple of minor variations. It's a fundamental part of the language design; Eich was thinking about Self and Smalltalk. That said, I don't write many "classes" in JavaScript either, but I do when it seems like a good idea. – Pointy Sep 07 '15 at 00:05
  • I think a big reason so many people find it confusing is that the workings of object context are so different from C++, Java, and C#, and yet all those languages and JavaScript use `this` as a keyword for a *similar*, but far from identical, purpose. All the Java programmers I know (including me) found it extremely weird in JavaScript until the point that the terminological similarity just has to be ignored finally sank in. – Pointy Sep 07 '15 at 00:08
  • @jfriend00 I made an edit using w3core's method below with some slight changes. I think this may fix the problem with 'instanceof' and the classes constructor being set to the function. Any thoughts on the new method? Thanks – wayofthefuture Sep 07 '15 at 23:33
  • @Dude2TheN - your "new" method is classic Javascript object type declaration. Nothing different about it at all except for maybe the one private variable `a` which is how Crockford shows it in that first Crockford reference. And, pretty much all the same need for `this` as anything else except for referencing the one private variable. So, yes you've overcome some of the previous limitations by going to the classic declaration mechanism that doesn't have those issues. – jfriend00 Sep 08 '15 at 01:13
  • Right, but if I have a class with 20 functions, and only 4 of them are public, I can work entirely in the private scope, and never have to use 'this.', except for at the bottom when exposing the public functions. Now I can focus on the inner workings of the class and have really easy to read code. Thanks again. – wayofthefuture Sep 08 '15 at 02:46
  • And it minimizes so beautifully. – wayofthefuture Sep 08 '15 at 02:53

1 Answers1

0

Take a look at that:

function ClassName (that) {
    var that = that || this;

    function methodName1 () {

    }

    function methodName2 () { 

    }

    that.methodName1 = methodName1;
    that.methodName2 = methodName2;
}

var case1 = new ClassName();
var case2 = new ClassName({ key: "value" });
var case3 = new ClassName(case2);
w3core
  • 119
  • 3
  • Very nice, I used this method and made an edit to the question, above. Can you tell me your thoughts on the modifications I made. I'd like to officially call it the "Revealing Class Pattern" :P – wayofthefuture Sep 07 '15 at 23:34
  • One question. Is it a good practice to use that syntax? All i can find across the internet is this topic here. And it looks a little bit wierd. – Aleksej Shovgenja May 30 '16 at 19:32