0

Right now I have the following static class in my application:

function Tools() { }
Tools.someFunction = function(arg1, arg2) {
   // do something
};

But I'm changing the architecture of my js file to one object literal containing all classes, so I'd need something like:

var app = {
   someController: function() {

   };
   tools: function() ...
};

I actually have two questions: - is this a good architecture in javascript to wrap all code in one big object? - how can I append that static class to this literal?

khernik
  • 2,059
  • 2
  • 26
  • 51
  • both are good but I think second one is better because in it we can also have private functions and variables too. but both are good – Muhammad Usman Sep 18 '15 at 12:38
  • First one can have private functions too.. – Rayon Sep 18 '15 at 12:39
  • Sidenote: OOP has no "static class" concept. There are static _members_ (methods or properties), not _classes_. Although a class containing only static members may be called static, however this is just a shortening term, not separate concept. – hindmost Sep 18 '15 at 13:00
  • I don't agree that this question should be closed as opinion-based. Granted, it's not posed well. It contains two parts, one which might be considered a matter of opinion (should I wrap a bunch of code in an object?), but another which is not (how do I adorn functions specified as object methods with additional properties?). If the OP cares to narrow the question, it can be re-opened. –  Sep 19 '15 at 03:51

2 Answers2

1

First of all, dismiss the word class and use prototype. ECMA-Script 6 and above are introducing class-based object-oriented programming, but your code seems to be in the track of using prototypal-based inheritance system. Well, in fact, you're just creating objects using a constructor function.

Using the right terms is a good start to communicate with the community.

Secondly, in JavaScript there're no static classes. Functions are essential in JavaScript, and they're still objects. Like objects, functions are expandable and you can add properties unless you call Object.preventExtensions on them.

It's just that your constructor function has also a property holding a function.

If you want to hold that constructor function as part of your app object, add it as a regular property:

var app = {
    Tools: function() {}
};

app.Tools.someFunction = function() {

};

is this a good architecture in javascript to wrap all code in one big object?

Sure. But use module pattern. There're tons of articles about the topic on the net. You might want to check this other Q&A: why module pattern?.

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • "your code is still using prototypal-based inheritance system" – where is it, I wonder. Otherwise, this is the answer I would recommend. :) – Pavlo Sep 18 '15 at 12:43
  • @Pavlo Haha, this is why I added the part **Well, in fact, you're just creating objects using a constructor function.**... – Matías Fidemraizer Sep 18 '15 at 12:45
  • 1
    @Pavlo Check my edit...... I've reworded the sentence :D – Matías Fidemraizer Sep 18 '15 at 12:45
  • "ECMA-Script 6 and above are introducing class-based object-oriented programming, but your code seems to be in the track of using prototypal-based inheritance system" – ES2015 Classes still use the prototype chain in the background ;) – nils Sep 18 '15 at 12:54
  • *ECMA-Script 6 and above are introducing class-based object-oriented programming*. Wrong. They are introducing syntactic sugar for people that want to use class-based OOP with a more streamlined notation. –  Sep 18 '15 at 12:55
  • There's nothing whatsoever wrong with using the term "class" informally to mean a category of objects created using constructor functions, or the constructor used to create such objects. –  Sep 18 '15 at 13:09
  • @torazaburo I know (the syntactic sugar thing) – Matías Fidemraizer Sep 18 '15 at 17:14
  • @torazaburo I prefer to call things by their exact term. They're not classes, thus, why should I call them *classes*? In JS it's better to call it just *object*... – Matías Fidemraizer Sep 18 '15 at 17:15
  • @torazaburo I hate the discussion "something is done under the hoods". For those who're going to use class-based OOP shouldn't know it's syntactic sugar over prototype system unless they need to extend a non-class oriented code with class-oriented code, or just to continue coding JS without classes....... – Matías Fidemraizer Sep 18 '15 at 17:21
  • @torazaburo In the other hand, the sentence "ECMA-Script6 introduces class-based object-oriented programming" isn't wrong. What has to do how it works under the hoods with the fact that **you're coding classes?** – Matías Fidemraizer Sep 18 '15 at 17:21
  • I guess we'll have to agree to disagree. JS has always had class-based object-oriented programming facilities, no matter what side of the argument about the semantics of using the words "class" or "object-oriented" as relates to JS one happens to stand on. It's just that using them required some syntactic somersaults. ES6 introduces no new features as regards classes. It just introduces new syntax. –  Sep 19 '15 at 03:46
  • @torazaburo actually this isn't true. JavaScript has been always an object oriented language which used prototypes to implement inheritance. Class based object oriented programming implies that you design classes. The fact that some js libraries already introduced the class semantics doesn't mean that vanilla JavaScript was already supporting the concept.... – Matías Fidemraizer Sep 19 '15 at 05:11
  • @torazaburo in fact, of you search in Google joopl github you'll find that I developed a class oriented library some time ago :D – Matías Fidemraizer Sep 19 '15 at 05:21
  • even if anyone is using `class` keyword, we shouldn't be saying that those are classes. they are objects or prototypes. at best we should either say "object classes" or "prototype classes" – Calvintwr Jun 19 '20 at 11:32
0

Is this a good architecture to wrap all code in one big object?

Not really in this day and age. Of course this approach reduces your footprint on the global namespace to one single name, like app. But the same can be accomplished more easily using ES6 modules. It's remarkably easy to shift over. You can continue to write

function Tools() { }
Tools.someFunction = function(arg1, arg2) {
   // do something
};

as you were before, but add

export default Tools;

Then, where you want to use this

import Tools from 'tools';
Tools.somefunction();

how can I append that static class to this literal?

With ES6 modules you don't need to, but there are many patterns described in many questions here. Some examples:

IIFE:

var app = {
   someController: function() {
     var f = function() { };
     f.someProp = 42;
     return 42;
   }(),

Initializer:

var app = {
   someController: function() { },
   init: function() {
     this.someController.someProp = 42;
     return this;
   }
}.init();

Explicit assignment:

var app = {
   someController: function() { }
};
app.someController.someProp = 42;

None of these are very fun to read or write. They have sort of a 2012-era feel about them. Use ES6 modules to avoid this and go back to writing regular old code.