Why is separation of JavaScript and HTML a good practice? [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have been reading about some good practices in JavaScript and one of them was Unobtrusive JavaScript. The first point caught my attention
Separation of functionality (the "behavior layer") from a Web page's structure/content and presentation
On the wiki page, one of the examples is that you should bind actions to events in JS files instead of in the HTML. This example
<input type="text" name="date" id="date" />
...
window.onload = function() {
document.getElementById('date').onchange = validateDate;
};
is favored over
<input type="text" name="date" onchange="validateDate()" />
However, I would say I'd prefer the second code with onchange attribute over the first one. My reasons for this are
It is easily readable and immediately clear what will happen on change (or any other event) on that element.
I don't have to got through JavaScript files and look where (and whether) the onchange event is bind and whether there are some other events such as click defined for #date.
Frameworks such as AngularJS have ng-click and is mixing up HTML structure with JS. Why shouldn't I?
The disadvantages of not using unobtrusive javascript that I have read about are
Polluting global namespace.
Creating long and unreadable inline code.
If the code for an event changes, you have to change it only in one place - that is in a JS file.
But I think that the disadvantages can be solved.
Instead of polluting namespace, create the app in one variable so the code would look like onchange="app.validateDate()" and no polluting would happen.
Inline code would not be written and would be separated in a function in JS file, then it'd be called like onclick="app.action();".
Isn't it the same as using a function in onclick attribute? Because in the end you have to make a change just in one function in both approaches whether it is $('input').change(function () {/* ... change ... */}); or app.action = function () {/* ... change ... */}.
So is it actually still considered a good practice?

This is a very broad topic and heavily opinion based. There is no one answer to everything. However, here are some observations:
You are polluting the namespace whatever you do. app.validateDate pollutes the namespace just as validateDate does, just by virtue of needing to have a globally accessible function name. In complex modern sites, there are tons of scripts competing for global names. Ideally you're never exposing any name globally, not even a namespace name.
.onclick = handler is not great either. You'd want:
document.getElementById('date').addEventListener('change', function () { .. });
This is even less obtrusive and allows several scripts to bind event listeners to the same element. Again, in complex modern sites one of the highest priorities you can have is to ensure nobody is stepping on anyone else's feet. You never know who else might be interested in the change event of that element in the future.
It is still more code to write it inline than elsewhere. Longer HTML code that is. HTML can already be very verbose. Anything you can move elsewhere you should. Reducing the amount of code in any one particular file is an art in itself and important for readability. Yeah, it's "just one more attribute"... on top of all the other attributes and elements and inline declarations you're also not avoiding. It's just piling up, and that's how code gets messy and unreadable and unmaintainable.
Reusability: document.getElementById(..).addEventListener can be written once in an external file and automagically reused across many different pages. <.. onclick=".."> needs to be repeatedly written every single time. DRY your code.
For tiny projects it often hardly matters. But again, sites are getting more and more complex. Business needs demand constant changes. Just one more analytics script, just one more Javascript based social widget, now change it all back, now keep all the versions of dependencies in sync, now rip it all out again and redesign for our 2.0 launch next week. Do it all with 10 other people in parallel without nuking each others code on every build or needing long sessions of resolving git-merge conflicts. In such an environment, every little bit of decoupling and indirection and flexibility helps.
Since you mention Angular:
Angular avoids some of these issues by employing a completely different template parsing model. When you write onclick=foo, then you need to bind to a global function name. However, when Angular does ng-click=foo, foo is a locally scoped entity in an ng-scope. It's not a global name. Angular separates between a controller and a view, where the controller essentially exposes a specific API on the $scope object which the view can use; both the controller and the view are still interchangeable as long as the specified API contract is kept (meaning as long as the $scope object keeps the same attributes).
All ng directives are evaluated against a custom scoping and evaluation engine which does not have much to do with Javascript's default modus operandi.

Related

How do I create a global variable in Qualtrics Question Text?

How do I create a variable to use in my text using a Qualtrics survey in multiple questions? I am not using any embedded data or making variations. The variable would be for the sole purpose of editing future drafts of my survey more efficiently. For example I want something like:
myvar = 100
Q1. If you have %myvar% and I take away 50 how much is left?
Q2. If you have %myvar% and I give you 70 how much do you get?
...
The more thorough the explanation the better!
You don't need any JavaScript for this. What you want to do is very easy in Qualtrics.
First, at the beginning of your survey flow assign a value to an embedded data field:
myvar = 100
Then pipe the value into your question text like:
Q1. If you have ${e://Field/myvar} and I take away 50 how much is left?
This Qualtrics Community answer might help you:
Add a function to the Look & Feel header that sets and returns the variable. Call the function from the JS in your questions.
This support article implies you can add JavaScript to any question that can set global variables, however it isn't recommended:
As with any implementation of JavaScript, we recommend abstaining from global variable creation as it can collide with existing functionality on the page.
Here's the workflow they describe (the below images are from the article):
Click "Add JavaScript" in the settings dropdown on a question, and enter your (global variable assignment) code in one of these functions:
addOnload() – Executed when the page is loaded.
addOnReady() – Executed when the page is fully displayed.
addOnUnload() – Executed when a page is unloaded (when the page is left).
As an aside, here's a good answer from Brian Rasmussen explaining the problems with global variables:
The problem with global variables is that since every function has access to these, it becomes increasingly hard to figure out which functions actually read and write these variables.
To understand how the application works, you pretty much have to take into account every function which modifies the global state. That can be done, but as the application grows it will get harder to the point of being virtually impossible (or at least a complete waste of time).
If you don't rely on global variables, you can pass state around between different functions as needed. That way you stand a much better chance of understanding what each function does, as you don't need to take the global state into account.

Should I use eval to patch/extend a widget?

This question may be too opinion based but since avoiding eval is almost unanimously agreed upon, I'd imagine there should be objective answers.
I'd like to "patch" an existing open-source widget to avoid creating my own custom build of it. But the parts I want to patch are internal functions which are completely hidden. IE:
function dostuff(){
function iCantBeEdittedSinceImNotAPrototypeMethod_unlessDoStuffIsCompletelyOverwrittenButItsVeryLong(){
//code that needs patched
};
};
The only way I can see of doing this is to turn the function dostuff into text, search and replace iCantBeEditted and then eval it.
How bad is this use of eval?
And the specific context that I'd like to use this with is fullcalendar's compareSegs function that decides sorts the order of events.
Concerns:
safety of eval
modifying a minified file. I can find the desired function with a somewhat fail safe pattern but even if I make it variable name agnostic, this could cause problems when fullcalendar is updated.
performance. This file is 72kb after being minified.
So, should I do this? Is there an easier alternative?

javascript - using function calls in html - bad or good?

Using angular brings lot of weird style of code. For example I always thought that this
<button onclick="myFunction()">Click me</button>
style I should not ever use, except when I would be lazy and want quick and dirty code. And I never used such style in projects and also I even thinked that this is bad.
Now when I see angular
here is the example:
<div enter="loadMoreTweets()">Roll over to load more tweets</div>
which is from there
http://www.thinkster.io/pick/IgQdYAAt9V/angularjs-directives-talking-to-controllers
which is good style by the tutorial. I dont get it. So then it means earlier example with onclick is also perfectly good? Then why nobody uses it at least these days when people use lot of jquery for example?
Let me cite from a book Angular, by Brad Green & Shyam Seshardi
Chapter 2 ... A Few Words on Unobtrusive JavaScript
The idea of unobtrusive JavaScript has been interpreted many ways, but the rationale
for this style of coding is something along the following lines:
Not everyone’s browser supports JavaScript. Let everyone see all of your content and use your app without needing to execute code in the
browser.
Some folks use browsers that work differently. Visually impaired folks who use screen-readers and some mobile phone users can’t use
sites with JavaScript.
Javascript works differently across different platforms. IE is usually the culprit here. You need to put in different event-handling
code depending on the browser.
These event handlers reference functions in the global namespace. It will cause you headaches when you try to integrate other libraries
with functions of the same names.
These event handlers combine structure and behavior. This makes your code more difficult to maintain, extend, and understand.
In most ways, life was better when you wrote JavaScript in this style.
One thing that was not better, however, was code complexity and
readability. Instead of declaring your event handler actions with the
element they act on, you usually had to assign IDs to these elements,
get a reference to the element, and set up event handlers with
callbacks...
...
In Angular, we decided to reexamine the problem.
The world has changed since these concepts were born...
... for most inline event handlers Angular has an equivalent in the form of
ng-eventhandler="expression" where eventhandler would be replaced by
click, mousedown, change, and so on. If you want to get notified when
a user clicks on an element, you simply use the ng-click directive
like this:
<div ng-click="doSomething()">...</div>
Is your brain saying “No, no, no! Bad, bad, bad!”? The good news is
that you can relax.
These directives differ from their event handler predecessors in that
they:
Behave the same in every browser. Angular takes care of the differences for you.
Do not operate on the global namespace. The expressions you specify can
To get more details, read the book: http://www.amazon.com/AngularJS-Brad-Green/dp/1449344852
EXTEND
Following the discussion in comments, I would like to add a more explanation.
As stated here: Wikipedia - AngularJS:
Angular is a framework, which goal is to augment browser-based applications with model–view–controller (MVC) capability, in an effort to make both development and testing easier
The Model–view–controller, a short extract from wikipedia:
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document).
A model notifies its associated views and controllers when there has been a change in its state. This notification allows views to update their presentation, and the controllers to change the available set of commands. In some cases an MVC implementation might instead be "passive," so that other components must poll the model for updates rather than being notified.
A view is told by the controller all the information it needs for generating an output representation to the user. It can also provide generic mechanisms to inform the controller of user input.
Summary:
The most important part here, is the fact, that View can publish the Controllers actions to the user. And this is exactly what the Function calls in HTML do represent.
This is a misunderstanding:
Using angular brings lot of weird style of code. For example I always thought that this
<button onclick="myFunction()">Click me</button>
style I should not ever use, except when I would be lazy and want quick and dirty code. And I never used such style in projects and also I even thinked that this is bad.
It is perfectly valid to use that style of code if you can decide what event handler to attach to the button when you render the HTML code. With jQuery we see many dynamically attached event handlers because many times the elements themselves are dynamically inserted or whether to attach an event listener or what to attach is dynamically decided.

Global variables in JS harmful? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
According to this article
http://www.mediaevent.de/javascript/globale-lokale-variablen.html
Global variables are in JS pretty dangerous.
I'm sorry that it's in German, but I'm gonna point out out the 2 main statements of the article.
The first is already in the 2nd paragraph of the head statement.
It says something like "In JS global var's are dangerous as they can get accessed by other scripts over the name" That's fine so far, as that's mostly the way why I want to use global var's don't I?
But in the article it sounds as this could happen randomly. and that's for sure not the expected behaving, is it?
But what is much more frightening me is the second last sentence. It forecasts that memory leaks will generated if a function that declares a
global variable is called multiple times.
But how could this happen if the name is still the same? how there can be multiple vars declared global with the same name?
Or is this article probably written by some one just "half-knowledge"? Or maybe just addressed to some one who isn't used to the difference between global and local at all?
Or is JS really behaving in this way?
Now a concrete example:
I want some one who logs in to my page to create a Random generated token and submit it by clicking login.
on each other button I want that this token is accessed by a different function and just submit it, so that just for a new login the key will be regenerated.
For that key I was thinking about using a global variable, which gets declared by one function and gets returned by another.
But as I will generate/regenerate the key possibly more then once, would this generate memory leaks? Or is this article I'm referring to probably just dramatizing?
If this is really the way JS is behaving, what would be a good way to make a variable accessable from different functions in my case?
The problem with globals is not memory, and it's not performance.
The problems with globals is entirely different. The problems are that they introduce global state and that scripts are not bound to a namespace.
Let's go through these problems one by one.
Having global state
This is the biggest issue here. Coding necessitates that the dependencies of a module be explicit and that communication between pieces of code is very clear.
When you have global variables which part of the code uses the variable is not nearly as clear and you can't be sure what part of the code needs it and what does not.
Let's say I have a Zoo project and I have a Bathe service that cleans an animal. Instead of passing Bathe around to each animal that needs it I have it on a global namespace and I just call Bathe(myAnimal).
Now I want to restructure my zoo and I want to know which animals need bathing because I want to optimize that. I have no way of knowing that other than going through my whole code. In order to see if my Giraffe needs bathing I have to read the entire code of the Giraffe class. If instead I passed Bathe to the constructor of Giraffe instead of using it or creating it inside giraffe (a concept called dependency injection) I can see that a Giraffe needs bathing just by reading the signature.
Now this can get way worse, what if I have state? If I'm actually changing a global variable in multiple places it becomes extremely hard to track. In a more than a few lines code base this means that you have state changing all around and no clear indication of who is changing it.
This is the main reason you should avoid globals altogether .
Scripts are not bound to a namespace
If I have two scripts on a page and my first script declares a A variable on the global namespace, the second script can access that variable. This is useful because scripts can interact this way but it's very harmful because it means that scripts can override each other's code, and communicate in an unclear way.
This of course is completely mitigated if you use a module loader like browserify or RequireJS which means your whole script only exposes two globals - require and define and then script loading is done through the loader.
This way the way independent pieces of code interact is well defined. That doesn't prevent you from creating variables on the global object, but it helps mitigating the need to do so in a uniform manner.
A note on security
Of course, anything on the client side is compromised, you can't do security or anything like that in client side JavaScript on an insecure browser (that is, you didn't prevent anything external on) because the client can just run arbitrary code on your code and read it.
There are three big problems with global variables:
name collisions
code complexity
garbage collection
Name collision
The problem with having variables in global scope is that you have less control over what else is in that scope. Your code uses a ga_ variable globally and works fine, but when you add a Google Analytics snippet that uses the same variable things unexpectedly fail and it can be quite hard to see why your shopping cart fails 2 out of 3 page loads.
If you can wrap your code in an IIFE to prevent having any variables in global scope, you should do that. Obviously there are cases where you actually want to have your code accessible globally (ex: jQuery library). In those cases, it is best practice to keep all your stuff in a single namespace (jQuery) with a relevant name.
Code complexity
It is usually a good idea to partition your code so that individual pieces have minimal interactions with each other. The more pieces interact the harder it is to make changes and to track down where bugs come from. Obviously a global variable can be accessed anywhere so when you have a problem with some code that accesses a global variable, you have to inspect every usage of that variable which can be quite a big pain. The thing to do to avoid these pains is to keep variables as local as they can be and encapsulate pieces of code so they can't interact with each other except through specific interfaces.
Memory leaks
In JavaScript you have little control over the garbage collection process. All that is guaranteed is that if you can access a variable it will not be garbage collected. This means that if you want something to be garbage collected, then you must make sure you can't access it anymore. While a global i variable which keeps a number won't be a big deal, as #Boluc Papuaccoglu mentioned when your global variable keeps more and more properties over time (an array of XHR requests for example, or array of created DOM objects), the memory consumption turn into a big deal.
All of these situations are worst case scenarios and you probably won't have issues with a small application. These recomendations have most value when you're starting to learn programming because they develop good habits and when you're working on complex applications when they save you time and money wasted on debug or difficult to do improvements.
Regarding memory leaks: Let's say you have a function, and within it you define a var, and use it for some purpose then return from the function. In this case, the memory used by the variable will be freed. However, if you relied on a global variable to do the same thing, then the memory would continue to be allocated long after your function exited. Extending the same scenario, imagine that your function adds properties to this variable with names that depend on the data the function is processing (like Order ID, Customer Name, etc.) Now, each time your function gets called, more and more properties will be appended to this variable and it will grow and grow.

Dependency Injection vs. Managed Dependencies vs. Global Object

I'm working within a Javascript + BackboneJS (an MVC framework) + RequireJS framework, but this question is somewhat OO generic.
Let me start by explaining that in Backbone, your Views are a mix of traditional Views and Controllers, and your HTML Templates are the traditional MVC Views
Been racking my head about this for a while and I'm not sure what the right/pragmatic approach should be.
I have a User object that contains user preferences (like unit system, language selection, anything else) that a lot of code depends on.
Some of my Views do most of the work without the use of templates (by using 3rd party libs, like Mapping and Graphing libs), and as such they have a dependency on the User object to take care of unit conversion, for example. I'm currently using RequireJS to manage that dependency without breaking encapsulation too much.
Some of my Views do very little work themselves, and only pass on Model data to my templating engine / templates, which do the work and DO have a dependency on the User object, again, for things like units conversion. The only way to pass this dependency into the template is by injecting it into the Model, and passing the model into the template engine.
My question is, how to best handle such a widely needed dependency?
- Create an App-wide reference/global object that is accessible everywhere? (YUK)
- Use RequireJS managed dependencies, even though it's generally only recommended to use managed dependency loading for class/object definitions rather than concrete objects.
- Or, only ever use dependency injection, and manually pass that dependency into everything that needs it?
From a purely technical point of view, I would argue that commutable globals (globals that may change), especially in javascript, are dangerous and wrong. Especially since javascript is full of parts of code that get executed asynchronously. Consider the following code:
window.loggedinuser = Users.get("Paul");
addSomeStuffToLoggedinUser();
window.loggedinuser = Users.get("Sam");
doSomeOtherStuffToLoggedinUser();
Now if addSomeStuffToLoggedinUser() executes asynchronously somewhere (e.g. it does an ajax call, and then another ajax call when the first one finishes), it may very well be adding stuff to the new loggedinuser ("Sam"), by the time it gets to the second ajax call. Clearly not what you want.
Having said that, I'm even less of a supporter of having some user object that we hand around all the time from function to function, ad infinitum.
Personally, having to choose between these two evils, I would choose a global scope for things that "very rarely change" --- unless perhaps I was building a nuclear powerstation or something. So, I tend to make the logged in user available globally in my app, taking the risk that if somehow for some reason some call runs very late, and I have a situation where one user logs out and directly the other one logs in, something strange may happen. (then again, if a meteor crashes into the datacenter that hosts my app, something strange may happen as well... I'm not protecting against that either). Actually a possible solution would be to reload the whole app as soon as someone logs out.
So, I guess it all depends on your app. One thing that makes it better (and makes you feel like you're still getting some OO karma points) is to hide your data in some namespaced singleton:
var myuser = MyApp.domain.LoggedinDomain.getLoggedinUser();
doSomethingCoolWith(myuser);
in stead of
doSomethingCoolWith(window.loggedinuser);
although it's pretty much the same thing in the end...
I think you already answered your own question, you just want someone else to say it for you : ) Use DI, but you aren't really "manually" passing that dependency into everything since you need to reference it to use it anyways.
Considering the TDD approach, how would you test this? DI is best for a new project, but JS gives you flexible options to deal with concrete global dependencies when testing, ie: context construction. Going way back, Yahoo laid out a module pattern where all modules were loosely coupled and not dependent on each other, but that it was ok to have global context. That global context can make your app construction more pragmatic for things that are constantly reused. Its just that you need to apply that judiciously/sparingly and there need be very strong cases for those things being dynamic.

Categories