JS: Best practice on global "window" object - javascript

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?!

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.

Related

Accessing private variables defined with WeakMap inside a derived class

I'm using the common WeakMaps pattern to emulate private variables inside es6 classes, but I cannot find a way to have "protected" variables, meaning variables that are private and that can be accessed through derived classes, eg:
var Window = (function() {
const _private = new WeakMap();
const internal = (key) => {
// Initialize if not created
if (!_private.has(key)) {
_private.set(key, {});
}
// Return private properties object
return _private.get(key);
};
class Window {
constructor() {
// creates a private property
internal(this).someProperty = "value";
}
}
return Window;
})();
If I create a subclass using the same pattern, how can I access someProperty in the subclass without having to define a getter method in the base class (thus completely defeating the whole purpose of having weakmaps for private properties) ?
If there's no elegant solution by using this pattern, what would be the best course of action to take?
I'm building a webapp which can have various "layered windows" displaying various products, loaded from a different script that makes few requests to .php endpoints to gather this information.
The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions
from a security standpoint most requests to other APIs would be done from a separate script handling validation of the payload so what I'm really trying to accomplish is to make reusable Window classes that can use some sort of "protected" variables across derived classes since it would definitely help me in the process of building this particular type of GUI
The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions
From the description of what you're really trying to do that you added to your question, it sounds like this isn't a "security" issue per se, but rather you're looking for the best programming implementation/convention for your local team that will be using this interface so that it will be clear to other developers which state is "protected" and for use only inside the implementation and not from the outside consumers of the objects.
If that's the case, I'd just go with the underscore convention where a property name on the object that starts with an underscore as in this._someProperty is meant only for internal use in the methods of the object itself (analogous to "protected" members in C++) and not for external use by consumers or users of the object.
Then communicate that in the doc for the implementation and verbally with the team you work with to make sure everyone not only understands that convention in the code you write, but so that they can also consistently use the same convention in their code.
Since it doesn't appear you have an actual security need here, the reasons to go with this type of leading underscore "convention" instead of more involved solutions that provide some real protection of the data from other developers (like what you were attempting to do):
Implementation is simpler
There is no performance degradation
Does not interfere with modularity and putting derived classes in separate files
Infinitely extensible to as many properties, as many classes
Easier to educate the team you're working with on how to do it
A saying once shared with me by a senior developer was that "my code should be as simple as it can be to meet the objectives (correctness, stability, testability, maintainability, extensibility and reuse)". This helped me to strive for simplicity in implementation and avoid over designing beyond what is actually needed.

Why using $rootScope with functions is not recommended?

While am looking into the FEQs of Angularjs I've seen below article:
$rootScope exists, but it can be used for evil
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
— AngularJS FAQ - $rootScope exists, but it can be used for evil
So My doubt is why $rootScope is not recommended for functions as a global function? Is there any performance issue?
I've answered this in the past, but it's good that you're asking these questions.
$rootScope exists, but it can be used for evil Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Non-isolated scopes are hierarchical, but most developers should be using directives that have isolated scopes. The very hierarchical nature of AngularJS's scope is the source of many bugs in angular apps. It's a problem I like to call scope bleeding where a scope property is modified magically somewhere in the DOM tree and you don't know why.
Angular's default behavior is to inherent scopes and this makes it tempting for one controller to update something managed by another controller, so on, and so on. This is how spaghetti connections between source code is created. Making it very difficult to maintain that code.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope.
No that's not correct. AngularJS allows you to define things like constants, values, and services. These are things that can be injected into routes, controllers and directives. That is how you make things accessible globally to your app, and this how you do it if you want to make your controllers or directives testable. A unit test writer doesn't know what properties should be in the $rootScope that a directive or controller depends upon. They have to assume that the $rootScope has not mutated to provide a service or data.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language.
The problem isn't $rootScope but what people are doing with it. Many apps add the current user, the auth tokens, and the session data into the rootScope. This ends up getting used heavily in templates (shows X if user logged in otherwise show Y). The problem is that the HTML doesn't communicate scope hierarchy. So when you see {{user.firstname + ' ' + user.lastname}} you have no idea where the variable user came from. The second problem is child scopes can shadow root properties. As in the previous example if a directive does this scope.user = 'bla bla bla'. It hasn't replaced the value on the rootScope. It's hidden it. Now you get some strange unexpected things in the templates, and you don't know why the variable user has changed.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
Angular's $cacheFactory and $templateCache are examples of services that exist only too store data. I think the author was trying to encourage the use of constants and values in Angular's modules, but that's not a good description to do that.
So My doubt is why $rootScope is not recommended for functions as a global function? Is there any performance issue?
The $rootScope is the only scope available during angular.config(..). It's during this time that the scope can be modified if this is the only time that you can do it. For example; you may need to inject an API key or Google anayltics variable before the app starts.
Functions on any scope are generally a bad idea. Mainly for the reason that everything in scopes is digested in expressions on the templates. Functions tent to hide heavy operations. It's impossible to tell how heavy a template is by reading the HTML when it calls a function. I've seen scope functions like getHeight() where the function itself performed 3 levels of nested loops. That function has to get called every time angular digests the watchers to see if it's changed. You should try to keep your templates as dry as possible.
Global Variables are Abused
$rootScope is pretty much a global variable and has its place but is definitely abused by most of the people that use it. These are the reasons Globals in general should not be used.
Non-locality -- Source code is easiest to understand when the scope of its individual elements are limited. Global variables can be read or modified by any part of the program, making it difficult to remember or reason about every possible use.
No Access Control or Constraint Checking -- A global variable can be get or set by any part of the program, and any rules regarding its use can be easily broken or forgotten. (In other words, get/set accessors are generally preferable over direct data access, and this is even more so for global data.) By extension, the lack of access control greatly hinders achieving security in situations where you may wish to run untrusted code (such as working with 3rd party plugins).
Implicit coupling -- A program with many global variables often has tight couplings between some of those variables, and couplings between variables and functions. Grouping coupled items into cohesive units usually leads to better programs.
Concurrency issues -- if globals can be accessed by multiple threads of execution, synchronization is necessary (and too-often neglected). When dynamically linking modules with globals, the composed system might not be thread-safe even if the two independent modules tested in dozens of different contexts were safe.
Namespace pollution -- Global names are available everywhere. You may unknowingly end up using a global when you think you are using a local (by misspelling or forgetting to declare the local) or vice versa. Also, if you ever have to link together modules that have the same global variable names, if you are lucky, you will get linking errors. If you are unlucky, the linker will simply treat all uses of the same name as the same object.
Memory allocation issues -- Some environments have memory allocation schemes that make allocation of globals tricky. This is especially true in languages where "constructors" have side-effects other than allocation (because, in that case, you can express unsafe situations where two globals mutually depend on one another). Also, when dynamically linking modules, it can be unclear whether different libraries have their own instances of globals or whether the globals are shared.
Testing and Confinement - source that utilizes globals is somewhat more difficult to test because one cannot readily set up a 'clean' environment between runs. More generally, source that utilizes global services of any sort (e.g. reading and writing files or databases) that aren't explicitly provided to that source is difficult to test for the same reason. For communicating systems, the ability to test system invariants may require running more than one 'copy' of a system simultaneously, which is greatly hindered by any use of shared services - including global memory - that are not provided for sharing as part of the test.
Source: http://c2.com/cgi/wiki?GlobalVariablesAreBad
Sharing data in Angular
When it comes to sharing data across controllers in Angular you should use a service. With your custom service you can create a getter and a setter method. You inject it to the controllers you need it and can use it in your app.
There exist no performance issues. It would actually boost your performance by a fraction of time, because you dont need to dependency-inject a lot of services.
But it's a big concern of design. Consider a large application with dozens and dozens of views, complex components and tied to a number of well known APIs (e.g. Twitter, Flickr, Facebook, OAuth, ...).
You wont develop this application alone. The following issues will arise:
Namespacing
You are working on the Facebook API, someone else is working on the Twitter API. You both think that using $rootScope for functions is a good idea and both write a $rootScope.login function. How would you resolve this when doing git merge? You need namespacing, alas, you need to develop two services myFacebookAPI, myTwitterAPI which then can implement the same interface for loggin in. (login(user,pw)). Note that this gives you the ability to abstract away the actual social network you are dealing with in the controller, when you can do something like:
$scope.callAction = function (action) {
var service;
if ($scope.serviceSelected === 'fb') {
service = myFacebookAPI;
} else {
service = myTwitterAPI;
}
service[action]();
};
Testing
When developing professionally, you write tests. Angular gives you tools to do automated tests for services, etc., but you wont be able to test something you assign to $rootScope in the same comfortable manner.
Other issues will arise too, but i think this should be enough for you to think about it on your own.

Organizing my JavaScript function library

Over time, I created a bunch of various JavaScript functions. Most of them are static functions, and do things like modify the appears of a date, create the select menu HTML from an array, etc.
I currently have them all in a file called "general.js" which is in turn directly called by my HTML page, and each of them look something like:
function modifyDate(data){....}
function makeArray(arr){....}
And then I use them as:
alert(modifyDate("12/14/2013"));
I am thinking this is a bad idea as it might conflict with other libraries. Instead, I am thinking of something like the following:
myLibrary={};
myLibrary.modifyDate= function(data){....}
myLibrary.makeArray= function(arr){....}
And them use them as:
alert(myLibrary.modifyDate("12/14/2013"));
Note that I am kind of making this up as I go. Please provide advice how I should best organize my JavaScript library. Thank you
What you're describing is called namespacing and is generally considered a good idea.
Some more discussion of namespacing can be found in this question: Why do they use namespaces in javascript?
In general the benefits of namespacing are:
Limiting pollution of the global scope and preventing naming collisions
Providing context for your function names (we'd expect different results for WindowUtils.getHeight and MenuUtils.getHeight for instance).
So your example would provide the first benefit, though not necessarily the second one if this is just a group of grab-bag functions. Whether thats a good thing or not is totally dependent on your individual project and what you're trying to do.
Note that if you're going to be namespacing, you may want to look into the module pattern which is a way of protecting the scope of your namespaces to allow for private variables/protected state. There's a good example in this answer to a similar question or you could check out this canonical blog post on the module pattern
In your case the module pattern would look something like this:
var myLibrary=(function(){
var privateVariable; //accessible by your functions but not in the global context
return {
modifyDate: function(data){....},
myLibrarymakeArray: function(arr){....}
};
}())

I want to stop using OOP in javascript and use delegation instead

After dabbling with javascript for a while, I became progressively convinced that OOP is not the right way to go, or at least, not extensively. Having two or three levels of inheritance is ok, but working full OOP like one would do in Java seems just not fitting.
The language supports compositing and delegation natively. I want to use just that. However, I am having trouble replicating certain benefits from OOP.
Namely:
How would I check if an object implements a certain behavior? I have thought of the following methods
Check if the object has a particular method. But this would mean standardizing method names and if the project is big, it can quickly become cumbersome, and lead to the java problem (object.hasMethod('emailRegexValidatorSimpleSuperLongNotConflictingMethodName')...It would just move the problem of OOP, not fix it. Furthermore, I could not find info on the performance of looking up if methods exist
Store each composited object in an array and check if the object contains the compositor. Something like: object.hasComposite(compositorClass)...But that's also not really elegant and is once again OOP, just not in the standard way.
Have each object have an "implements" array property, and leave the responsibility to the object to say if it implements a certain behavior, whether it is through composition or natively. Flexible and simple, but requires to remember a number of conventions. It is my preferred method until now, but I am still looking.
How would I initialize an object without repeating all the set-up for composited objects? For example, if I have an "textInput" class that uses a certain number of validators, which have to be initialized with variables, and a class "emailInput" which uses the exact same validators, it is cumbersome to repeat the code. And if the interface of the validators change, the code has to change in every class that uses them. How would I go about setting that easily? The API I am thinking of should be as simple as doing object.compositors('emailValidator','lengthValidator','...')
Is there any performance loss associated with having most of the functions that run in the app go through an apply()? Since I am going to be using delegation extensively, basic objects will most probably have almost no methods. All methods will be provided by the composited objects.
Any good resource? I have read countless posts about OOP vs delegation, and about the benefits of delegation, etc, but I can't find anything that would discuss "javascript delegation done right", in the scope of a large framework.
edit
Further explanations:
I don't have code yet, I have been working on a framework in pure OOP and I am getting stuck and in need of multiple inheritance. Thus, I decided to drop classes totally. So I am now merely at theoretical level and trying to make sense out of this.
"Compositing" might be the wrong word; I am referring to the composite pattern, very useful for tree-like structures. It's true that it is rare to have tree structures on the front end (well, save for the DOM of course), but I am developing for node.js
What I mean by "switching from OOP" is that I am going to part from defining classes, using the "new" operator, and so on; I intend to use anonymous objects and extend them with delegators. Example:
var a = {};
compositor.addDelegates(a,["validator", "accessManager", "databaseObject"]);
So a "class" would be a function with predefined delegators:
function getInputObject(type, validator){
var input = {};
compositor.addDelegates(input,[compositor,renderable("input"+type),"ajaxed"]);
if(validator){input.addDelegate(validator);}
return input;
}
Does that make sense?
1) How would I check if an object implements a certain behavior?
Most people don't bother with testing for method existance like this.
If you want to test for methods in order to branch and do different things if its found or not then you are probably doing something evil (this kind of instanceof is usually a code smell in OO code)
If you are just checking if an object implements an interface for error checking then it is not much better then not testing and letting an exception be thrown if the method is not found. I don't know anyone that routinely does this checking but I am sure someone out there is doing it...
2) How would I initialize an object without repeating all the set-up for composited objects?
If you wrap the inner object construction code in a function or class then I think you can avoid most of the repetition and coupling.
3) Is there any performance loss associated with having most of the functions that run in the app go through an apply()?
In my experience, I prefer to avoid dealing with this unless strictly necessary. this is fiddly, breaks inside callbacks (that I use extensively for iteration and async stuff) and it is very easy to forget to set it correctly. I try to use more traditional approaches to composition. For example:
Having each owned object be completely independent, without needing to look at its siblings or owner. This allows me to just call its methods directly and letting it be its own this.
Giving the owned objects a reference to their owner in the form of a property or as a parameter passed to their methods. This allows the composition units to access the owner without depending on having the this correctly set.
Using mixins, flattening the separate composition units in a single level. This has big name clash issues but allows everyone to see each other and share the same "this". Mixins also decouples the code from changes in the composition structure, since different composition divisions will still flatten to the same mixed object.
4) Any good resources?
I don't know, so tell me if you find one :)

What's the proper term for this: "javascript object full of functions"?

I've been using this kind of programming pattern lately in order to group logically related functions:
FruitMethods = {
url: "some/path/to/something.durk",
get: function(data) {$.ajax(url, data)},
delete: function(something) { some more function stuff....}
}
You get the picture right? It doesn't seem to really meet the definition of a Class... or does it? A Mixin? Something else? Javascript Object Full Of Functions And Maybe A Variable? JOFOFAMAV?
My vote if for JOFOFAMAV.
PS: Feel free to also chime in with your thoughts on whether or not this is a good practice.
Functionally, it's an object with properties. So, then your question becomes more about what common name would one call it.
Because it has no instance data and doesn't appear like one will be creating new instances of it (e.g. like a class), then it is most like a namespace which is just a named wrapper for a bunch of properties where properties can be any sort of data or functions.
Namespace objects are useful for a bunch of reasons:
Limiting the use of the top level, global namespace thus lowering the chance of a name conflict with other scripts.
An organizational structure/convention for collecting a group of related data or functions.
A hierarchical scheme that makes it easier for categorizing or organizing methods and/or data and referring to them with a simple scheme of category.method like Fruit.get()
I would call that a namespace.
That's a form of singleton - which is basically an object without an external definition: you don't have a 'class' definition and then create instances of that class.
One thing to know about this type of structure is that all of the methods of the object are public ( that may or may not be a problem).

Categories

Resources