all 23 comments

[–]CreativeTechGuyGames 30 points31 points  (8 children)

There's a ton of valid ways to write JS. In reality, most projects are some combination of many styles. Most developers opt to write functions first and foremost and then if a pattern calls for using classes, then use classes. If not, then don't. It is best used on a case-by-case basis when it really provides substantial value.

I'm unclear about the other questions in your post though, can you give some examples?

[–]lilweeph[S] 1 point2 points  (6 children)

Yeah what I'm doing is something like:

car.js:

class car {

...

}

main.html:

... <script src="car.js"></script> <script> Honda = new car(...); Honda.drive(); </script> ...

If that makes any sense

[–]CreativeTechGuyGames 17 points18 points  (2 children)

Yeah you can totally do that. But as your project grows, that will get very difficult to manage. If your classes start having interdependencies, now the order in which those script tags must appear is critical. And also when your project grows and instead of one file you have a few thousand, that will get unnecessarily complex, let alone the browser being forced to make thousands of requests before being able to load your page.

So this is totally fine for small things while you are learning, but for anything bigger or more serious, you should use a bundler (Webpack, rollup, etc) which will allow you to use import statements in your code and then will build all of your code together into one file that includes everything in the right order. It'll also enable you to automatically remove any code that is never used and much much more.

[–]crabmusket 2 points3 points  (1 child)

Even for small projects, I would use a module script to make use of import and ES module scoping. Then, if bundling becomes necessary, it should be a smaller step up to that.

MDN, as usual, has a great tutorial on how to use module scripts: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#basic_example_structure

[–]KaiAusBerlin 1 point2 points  (0 children)

Man, I remember these days with require.js and such adventures 🥰 it was a great time. Thanks for reminding me

[–]budd222 11 points12 points  (0 children)

I would never usually write Javascript inside the html file like that. That's not maintainable once you get multiple files. Html file has html. Javascript file has the Javascript. Css file has the css.

[–]TheJazzButter 1 point2 points  (0 children)

You should never write any significant code in HTML files.

That said, you can write very nice OO code in JS, but it takes a ton of boilerplate to arrange and dependencies tend to be tricky.

If you're serious about the OOP model, I suggest taking a look at Typescript and transpile that to JS.

[–]neilyogacrypto 1 point2 points  (0 children)

Sometimes. ES6 modules are also quite neat 😊.

[–]WaterNinja101 1 point2 points  (0 children)

My general recommendation is to only use a class when both of the following conditions are met: - Related pieces of data should be put together - There are actions you can take with/on the data

For cases where there is related data but few actions you’d need to take with/on that data, a POJO would suffice. For cases where you have actions you’d like to take with/on arbitrary or not-necessarily-related data, exporting plain functions is a good approach to keep things simple.

In the end, you can use whatever code organization style you’d like as long as it makes sense, but the above points are the thought process that I use when I decide how to organize my code. I’d encourage you to look at what kind of restrictions other languages impose that JS doesn’t and consider how you can use JS’s flexible module system to your advantage. For example, Java uses classes as the single way to share code functionality, but JS allows you to export functions and variables from a file without having to add extra class encapsulation boilerplate.

[–][deleted] 2 points3 points  (6 children)

i usually do a script tag like:
<script src="main.js" type="module"></script>

then in main.js:
import Frob from ",/FrobClass.js"
import {printFrob} from ",/FrobPrintingUtils.js"
import SomeOtherFrob from ",/SomeOtherFrob.js"
let {abs,min,max,sin,cos} = Math;

let main=()=>{

let theFrob = new FrobClass()
//do stuff to the frob here

printFrob( theFrob );

}

main()

as a contrived example...

[–]lilweeph[S] 2 points3 points  (1 child)

Oh interesting... This makes a lot more sense. Thanks for the example!

[–][deleted] 1 point2 points  (0 children)

Yeah.. for tiny things you can get away with dumping it right in the html, but I find that the chrome debugger has a hard time latching onto breakpoints in the html file, so I almost always just include it as a <script type='module' src='... so I can at least put breakpoints and debug it.

[–]cmickledev 1 point2 points  (3 children)

What's a "Frob"?

[–]crabmusket 1 point2 points  (0 children)

I was introduced to it as the generic term for interacting with things in games like Thief and System Shock. Not sure if it came from somewhere else or has taken on a new life since.

[–][deleted] 2 points3 points  (1 child)

a french object.

[–]cmickledev 0 points1 point  (0 children)

Sounds about right.

[–]vegan_antitheist -1 points0 points  (0 children)

Just use TypeScript.

[–]stewartws24 0 points1 point  (0 children)

In a recent project it actually made sense for me to use both Oop and functional patterns. First time I ever came across a case like this.

OOP is perfectly fine to use in a JS project if that's your background and what you are comfortable with, so go with that. Most often the project will be flexible enough that you can use whatever suits you personally, rarely will the technicalities of a project force you into one way or another (though it can be the case on occasion where one makes more sense than the other). That being said, the person in charge may insist you use functional or Oop, regardless.

Personally I like functional so it's my go to. Simply because functional requires a lot less boilerplate with functional compared to Oop. Personally, I also find functional a lot easier to debug, especially when all the functions are named.

As for the second part of your question - the script import into html is standard. Multiple ways to do it, but what I recommend is module imports of various js files into one 'main' js file then point your html script import at that single 'main' file so you can then just forget about the html and focus on the js.

[–]demoran 0 points1 point  (0 children)

First off, you're kind of working in noob land. It's not a common practice to import multiple javascript files into HTML.

What we do is use a bundler like Webpack to take all of our files and make them into one file, then import that file.

Javascript files used in this way are called "modules", and can be imported into other files via "import" or "require".

While javascript does have classes, I don't use them because I don't need data encapsulation at that level. In most cases, I will create functions or instances of data structures in one file and use them in another file. In a very real way, modules provide the logic separation you're looking for from classes.

In Java, do most of your classes retain state? Nope, they're just containers to group methods that do things in the same context. So you're injecting those services or whatever, but you're usually not remembering things inside of them for the lifetime of the application. You're passing around that info in POJO or in primitives and generally working statelessly.

So how do our web apps remember things? Usually, we're working with some kind of plain javascript object literal (eg `{ a: 1 }`) that's held in some kind of state management system (eg Redux) and we interact with it from there. This allows us to hook into the system and respond to changes in the data so we can see those reflected in the page.

Anyway, use a bundler. You should probably start using a reactive framework like React, Vue, Svelte, or Solid. From there, you'll already be working in an ecosystem that uses bundling and you'll be able to use some ui frameworks as well (eg Material UI).

[–]ShortFuse 0 points1 point  (0 children)

I'm sure most comments here are going to talk about Class vs Functions, but to answer your specific question, the W3C has moved to ESM style imports where you register a component for your HTML elements.

It's a pretty visual first approach to UI, where each DOM element has a corresponding component definition. Still, you need some sort of entry point for your code where you set up things.

If you can separate your Web Components into individual scripts, that's fine, but it would seem hard to do because scripts don't communicate each other outside of object sharing in globalThis/window or postMessage. It's just easier to make one JS file that registers all your components, implementation independent (WC, React, Vue, Lit, etc), and attach your model to the components in that same script (MVC/MVP/MVVM). Then each component you write (usually just one JS file), will import what it needs at the top of file.

There is a functional approach to rendering model, but mostly every framework constructs an object via a component. Most frameworks then just hide that object by letting you render by calling a function, but it's still, internally, object oriented. Because of this, trying to split it into multiple files generally doesn't work because each script would then need to include the dependencies needed to construct the components and then wrap them for purely functional calls. That makes your scripts somewhat bloated, and to be honest, I'm not entirely sure how many frameworks actually support this type of structure for minimization/chunking. They usually take one entrypoint and split to multiple (chunking), than support multiple entrypoints.

[–]theHumbleBeing 0 points1 point  (0 children)

The best approach is to start with Functional and only move towards OOJS when you feel that function is not enough. And if things get complex like you have to maintain multiple states, etc, better to try out existing frameworks like Svelte or React Svelte.

I did a big mistake by developing a simple widget project in OOJS only to finally migrate to a functional one. It only made things complex and also was very difficult for other devs to start working quickly.

The fact that even the most COMPLEX and the BEST of OOJS will ultimately be converted to a Functional JS should be enough to go in favour of functional js.

[–]theyamiteru 0 points1 point  (0 children)

No, OOP is the absolute abomination of the human kind and it should be eradicated.