2

Following a rapid-prototyping approach, I am developing an application in Marionette.js/backbone.js and heavily used the window-object to bind collections and views to the global stack (e.g. window.app.data, window.app.views).

Of course, it is always better (smoother!) to encapsulate objects in a single class and pass them as parameters where needed. However, this has some limitations when an app and its potential use-cases become really big. And as the data I deal with comes from an API and therefore would be anyway accessible to anybody interested, does that justify storing data in the window-object? Or are there other best-practices in ES6 (or especially Marionette.js) to achieve the same results, but in a more private manner?!

Felix A.
  • 61
  • 1
  • 4
  • 1
    One way to avoid polluting the global `window` object is to create a [namespace for your app](https://stackoverflow.com/a/42372930/1218980). – Emile Bergeron Jan 08 '18 at 14:46
  • Well, I could not yet find a namespace-based solution that integrates nicely with Browserify/AMD-modules (such would be read-only, isn't it?!). Additionaly, I do not want to attach objects to the namespace, but actual instances, so that I can read AND write already fetched data. – Felix A. Jan 09 '18 at 13:35

1 Answers1

5

I already go into details about a simple namespacing pattern in JavaScript in another answer. You seem to be already close to this with window.app.data etc.

But it looks like you have a lot of misconceptions about how JavaScript works.

a namespace-based solution that integrates nicely with Browserify/AMD-modules

Then why not use RequireJS? Browserify? or Webpack? There's nothing that a global ridden spaghetti code can do that a modular approach can't do better.

such would be read-only

No. While not impossible to set an object property to read-only, you must explicitly do it with something like Object.seal or Object.freeze.

I do not want to attach objects to the namespace, but actual instances

JavaScript do not have "namespaces" as part of the language, it's just a pattern to scope all your code within literal objects (key-value).

You can put whatever you'd like.

const MyNamespace = {
  MyType: Backbone.Model.extend({ /*...*/ }),
  instance: new Backbone.Model(),
  anyValue: "some important string",
};

Ideally, you would define the namespace within an IIFE to avoid leaking any variable to the global scope.

const app = app || {};

app.MyModel = (function(app){
  return Backbone.Model.extend({
    // ...
  });
})(app);

[...] data I deal with comes from an API and therefore would be anyway accessible to anybody interested

Even if the data is contained within a module that do not leak to the global scope, anybody can access the data. That's how JavaScript works, it's in the user's browser, he can do whatever he wants with the code and the data.

does that justify storing data in the window-object?

No.

Or are there other best-practices in ES6

ES6 has nothing to do with the architecture and patterns you take for your app.

but in a more private manner?!

Like I said earlier, privacy in JavaScript can't be expected.

[encapsulate objects in a single class and pass them as parameters where needed] has some limitations when an app and its potential use-cases become really big.

That's just incorrect. It's the other way around. Software patterns exist solely to help alleviate any limitations that arise as a project grows in scope.

There are multiple patterns you can use that will help deal with the complexity of a bigger app, like:

  • Modular approach with components
  • Dependency injection
  • Service containers
  • Factories
  • Events
  • etc.

I didn't read specifically this book, but JavaScript Design Patterns seems to be a good way to learn more and it demonstrates specific implementations of software patterns in JS.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129