Unclear javascript/jquery programming pattern - javascript

I am working on a web project where in the UI jsp pages. All the jquery/javascript methods are called via this pattern
A.b.c.d.methodName()
There are many .js files imported in the jsp page. So I have to search in Eclipse IDE
to track the method js file.
In the js file which has an entirely different name not "A.b.c.d", the method is declared as
methodName: function()
{ // logic }
Can anyone tell me what is this style/pattern of using jquery.

JavaScript never looks for file names, the "namespacing" you see there is achieved by objects nested in each other as properties.
For example if you create an object like:
var A = {
b: {
c: {
d: {
methodName: function () {
console.log('What a nice method!');
}
}
}
}
};
You can call it like this:
A.b.c.d.methodName();
Or you can add methods later in your code:
var irrelevantName = function () {
console.log('This method is even nicer');
};
A.b.c.method2 = irrelevantName;
And call it by:
A.b.c.method2();
There is a much used extend method which has surfaced in lot of JavaScript frameworks, like jQuery or MooTools. This provides a way for safely extending an object while preserving original values if present.
You can use the jQuery one like:
$.extend(A.b.c.d, {
method3: function () {
console.log('An other nice method');
}
});
And as you expect, it can be called as:
A.b.c.d.method3();
JavaScript libraries usually use namespacing: they create some kind of an object and populate it with all their methods. This way they don't pollute the global namespace with their methods.
There are a lot of ways to add new properties to an object in JS, so it is not always obvious how a method is added to an object, but it is safe to say that file names have nothing to do with it.
For further reading on the subject, I would recommend this google search. Basically any of the top 20 results should explain how namespaces are created and used in JavaScript.
On a footnote: I'm not sure how does the Eclipse tooling support JS, but as it is not a trivial problem (object structure can be modified on the fly) I would not be surprised if Eclipse had no understanding of JavaScript namespacing.

Looks like it has some sort of namespacing. The code could be using could be the AMD pattern? But again, if it's JSP it might be old....

Related

When should we load the function, if we want to add a function to a prototype using React?

I am trying to add a toCamelCase function to the String prototype in React with TypeScript.
Here is what I did, in a toCamelCase.d.ts file:
interface String {
toCamelCase(): string;
}
String.prototype.toCamelCase = function (): string {
return this[0].toUpperCase() + this.slice(1).toLowerCase();
};
Now I am just wondering when and in which file should I load this script so I can get access to it.
I am aware that I can simply define a function and use that.
However, I am curious how to do it with prototype and what would be the downside doing things like this if there are any.
Where to do it?
In main.js or index.js or any other file that bootstraps your application
What are the downsides?
You can never know if one of the libraries that you use using relies on String.prototype being unaltered. It can cause major issues that you will have a hard time finding.

The way to use custom method everywhere without requiring the module everywhere

I am using Node.js. I defined a custom method to the String obj like this:
if (!String.prototype.myMethod) {
String.prototype.myMethod= function () {
//do something
return this;
};
}
I found that myMethod maybe used in many different files, so that I have to require the file where this piece of code in. Is there any way that does the many 'requires' ?
Don't do that.
Node is intentionally designed in a module pattern, where each module gets it's own scope to run in and without polluting the global variables. This very intentional and very important.
https://nodejs.org/api/modules.html#modules_the_module_wrapper

Convert a large javascript file into multiple files

My question: How would one best go about breaking a large, monolithic javascript object literal into multiple, discrete, files?
I have a single javascript file that consists of an object literal with many methods attached to it. It's getting quite long and I want to break it into smaller parts that can more easily be managed.
I've heard I can use AMD or CommonJS to organize things, I've heard I should use RequireJS, that I should use Webpack or Browserify, that I should use any number of other tools/techniques. After looking at these things I am confused as to what the best approach is.
How would you do it? How would you take a single object literal consisting of a few thousands lines of javascript (made up of functions like "search" and "login" and "user") and reorganize it into multiple files that are more easily dealt with by a group of developers? The single, giant file thing is just getting to unwieldy and the options seems to varied and unclear. This is a fairly simple app that uses vanilla JS, a little jQuery and sits on top of a Grails backend.
I think the question is pretty clear but if you really need code to look at here is an example of the sort of object literal I am talking about:
var myObj = {
foo: "one",
bar: "two",
baz: false,
deez: -1,
login: function() {
// lots and lots of code
},
user: function() {
// lots and lots of code
},
beers: function() {
// lots and lots of code
},
varieties: function() {
// lots and lots of code
}
init: function() {
myObj.login.init();
myObj.user.init();
// lots of jQuery document.ready stuff
}
}
myObj.init();
You will a lot of suggestions and approaches to solve your problems, and I can't say any of them are wrong, they are just different.
My approach would be to use ES6 and its native module support.
To accomplish this I always use my own boilerplate named fabric which uses Webpack to compile the modules, Browsersync to help you on your development, Tape for unit testing, SASS for your CSS preprocessing, and Babel to compile a compatible ES5 bundle that you can easily use in your application.
Now, the way to use the ES6 modules is something like this with named exports:
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
Or using default exports:
//------ myFunc.js ------
export default function () { ... };
//------ main1.js ------
import myFunc from 'myFunc';
myFunc();
You can learn more about ES6 modules at 2ality
Here's the pattern I use:
When possible, break concepts into their own sub-object
Regardless of sub-objects or not, declare any non-broken-up properties first, then add to it as needed
If the files are across multiple files and you do not wish to use sub-objects per-file, use a temporary object to hold additional properties, and then extend the original.
Sample:
var myObj = {
foo: "one",
bar: "two",
baz: false,
deez: -1
}
myObj.login = function() {
// lots and lots of code
};
myObj.user = function() {
// lots and lots of code
};
myObj.drinks = {
beer: function() {},
wine: function() {},
sunnyDelight: {
drinkIt: function() {},
burp: function() {}
}
};
myObj.init = function() {
myObj.login.init();
myObj.user.init();
// lots of jQuery document.ready stuff
}
myObj.init();
Note that "drinks" is a concept unto itself, containing multiple properties and methods. Your concepts might be something like "ui", "utils", "data" or whatever the role of the contained properties happens to be.
For the extend point I made, there's not much code needed there either
// "utilities.js"
var myObj = {
// a bunch of properties and/or methods
};
myObj.moreStuff = "more stuff!";
and then in another file you have two choices. Either add to the object without overwriting it (you will need the dot-notation to do this):
// "ui.js"
var myObj = myObj || {};
// adds the render object to the existing myObj
myObj.render = {
header: function() {},
dialogBox: function() {}
}
The above works particularly well if you sub-divide your concepts... because you can still have fairly monolithic objects that will not trample over the rest of myObj. But maybe you want to add directly to myObj without trampling and without subdividing concerns:
// "ui.js"
var myObj = myObj || {};
// ultimately, the CONTENTS of this object get merged into the existing myObj
var myObjSupplement = {
header: function() {},
dialogBox: function() {},
heroBiscuit: "A yummy biscuit made from heroes!"
}
// using jQuery here, but it's not the only way to extend an object
$.extend(myObj, myObjSupplement)
I don't see TOO many opportunities to use the above, since myObjSupplement is now in the global namespace and defeats the purpose of limiting additions to the global namespace, but it's there if you need it.
[edited to add: ]
It might not go "without saying" as I thought-- but dividing into many different files probably works best if you have a build process in place that can concatenate them into one file suitable for minifying. You don't want to have 100 or even 6 separate files each requiring a synchronous HTTP call to fetch.
There are more modern and possibly 'better' approaches with technologies like AMD/RequireJS... but if the question is, "how do I divide up an object literal into several files", the above answer I've given is one I can stand behind.
While there are automated ways of doing this I'm sure, and I am also interested in seeing the answers this question gets, I would recommend simply going in and moving the method definitions into different files and calling the functions normally method(param); and linking the files to your html page.
This would serve multiple purposes, including the one you are looking to acheive of breaking your code down into more manageable modules. Among those purposes also include the fact that instead of having those definitions written to memory for every instance of the object, you would only define it once and make references to it whenever you need it.
Sorry I can't be of more help without actually seeing the JavaScript File.
You can reference this stack overflow example if you need more guidance in achieving this.
You don't have to have all of the methods defined in your objects or classes, it's better to modularize these methods into different files and use the <script src="path/to/your/script.js"> </script> tags to include them all with your html/php page

Dojo module loading in general

Coming from Java/C# I struggle to understand what that actually means for me as a developer (I'm thinking too much object-oriented).
Suppose there are two html files that use the same Dojo module via require() in a script tag like so:
<script type="text/javascript">
require(["some/module"],
function(someModule) {
...
}
);
</script>
I understand that require() loads all the given modules before calling the callback method. But, is the module loaded for each and every require() where it is defined? So in the sample above is some/module loaded once and then shared between the two HTMLs or is it loaded twice (i.e. loaded for every require where it is listed in the requirements list)?
If the module is loaded only once, can I share information between the two callbacks then? In case it is loaded twice, how can I share information between those two callbacks then?
The official documentation says "The global function define allows you to register a module with the loader. ". Does that mean that defines are something like static classes/methods?
If you load the module twice in the same window, it will only load the module once and return the same object when you request it a second time.
So, if you're having two seperate pages, then it will have two windows which will mean that it will load the module two times. If you want to share information, you will have to store it somewhere (the web is stateless), you could use a back-end service + database, or you could use the HTML5 localStorage API or the IndexedDB (for example).
If you don't want that, you can always use single page applications. This means that you will load multiple pages in one window using JavaScript (asynchronous pages).
About your last question... with define() you define modules. A module can be a simple object (which would be similar to static classes since you don't have to instantiate), but a module can also be a prototype, which means you will be able to create instances, for example:
define([], function() {
return {
"foo": function() {
console.log("bar");
}
};
});
This will return the same single object every time you need it. You can see it as a static class or a singleton. If you require it twice, then it will return the same object.
However, you could also write something like this:
define([], function() {
return function() {
this.foo = function() {
console.log("bar");
};
};
});
Which means that you're returning a prototype. Using it requires you to instantiate it, for example:
require(["my/Module"], function(Module) {
new Module().foo();
});
Prototyping is a basic feature of JavaScript, but in Dojo there's a module that does that for you, called dojo/_base/declare. You will often see things like this:
define(["dojo/_base/declare"], function(declare) {
return declare([], {
foo: function() {
console.log("bar");
}
});
});
In this case, you will have to load it similarly to a prototype (using the new keyword).
You can find a demo of all this on Plunker.
You might ask, how can you tell the difference between a singleton/static class module, and a prototypal module... well, there's a common naming convention to it. When your module starts with a capital letter (for example dijit/layout/ContentPane, dojo/dnd/Moveable, ...) then it usually means the module requires instances. When the module starts with a lowercase letter, it's a static class/singleton (for example dojo/_base/declare, dijit/registry)
1) dojo require, loads the module once and then if you called it again require() will simply return if the package is already loaded. so the request will be called once and it will also call any dependencies once.
but all that if you are in the same HTML page if you leave the page and call the same module in a different page then it will be called from the server. you can also use cache in your config settings so things will be cached in the browser and the file will or not by setting the cacheBust to true if you want a fresh copy or false if you want things to be cached.
2) if you are in the same html page and domain, the module didn't change the module will be the same and you can share values and any change you make you can get it from anywhere unless you call a new instance. but that is not possible between different html pages.
3) not it is not like a static classes or methods from what I understand static methods A static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields..
dojo work differently it is a reference for an object if you did it in that way :
define(function(){
var privateValue = 0;
return {
increment: function(){
privateValue++;
},
decrement: function(){
privateValue--;
},
getValue: function(){
return privateValue;
}
};
});
This means every bit of code loads that module will reference the same object in memory so the value will be the same through out the use of that module.
of course that is my understanding please feel free to tell me where I am wrong.

how to unit-test private methods in jquery plugins?

Perhaps this is a bit of a novice JQuery question but:
proper jquery plugins are written inside a closure
thus only methods defining the plugin interface are accessible from the outside
sometimes (or many times) one may need helper methods that it doesn't make sense to expose as part of plugin interface (for example because they alter internal state).
how do those get unit-tested?
For example, looking at blockUI plugin, how can methods install, remove, reset get unit-tested?
To draw a parallel, in Java I would:
create a BlockUI interface containing public methods only (by definition)
create a BlockUIImpl class implementing the above interface. This class would contain install(), remove(), reset() methods that could be public, or (package) protected
So, I would unit-test the Impl but client programmers would interact with the plugin via BlockUI interface.
The same applies here as with any other language and testing privates: To test private methods, you should exercise them via the public interface. In other words, by calling your public methods, the private methods get tested in the process because the public methods rely on the privates.
Generally private methods are not tested separately from the public interface - the entire point is that they are implementation details, and tests should generally not know too much about the specifics of the implementation.
Code written inside a function in JavaScript, or closure as you called it, is not necessarily isolated from the outside of that function.
It is useful to know that functions have visibility of the scope in which they are defined. Any closure you create carries the scope, and therefore functions, of the code that contains it.
This simple example with a jQuery plugin and an artificial "namespace" might serve to prove this assumption:
// Initialise this only when running tests
my_public_test_namespace = function(){};
jQuery.fn.makeItBlue = function() {
makeItBlue(this);
function makeItBlue(object) {
object.css('color','blue');
}
if(typeof my_public_test_namespace != "undefined") {
my_public_test_namespace.testHarness = function() {
return {
_makeItBluePrivateFn: makeItBlue
}
};
}
};
$("#myElement").makeItBlue(); // make something blue, initialise plugin
console.debug(my_public_test_namespace.testHarness()._makeItBluePrivateFn);
But don't forget you shouldn't really test privates. ;)
I came up with the same question and after navigating and finding answers that not really apply, here's what I ended up to solve a similar problem.
Problem: "I have a widget that has a behavior I want to test to ensure it's working as expected, some of the methods are called internally because they have to solve internal behavior, exposing them as public does not make sense because they wont be called from outside, testing the public methods means you wont test the internals of the widget, so finally what can I do?"
Solution: "Creata a test widget that exposes the methods you are interested in testing and use them in the qunit, here is the example:"
// Namespaces to avoid having conflicts with other things defined similarly
var formeditortest = formeditortest || {};
// widget that inherits from the container I want to test
$.widget( "app.testcontainer", $.app.container, {
executeDrop: function(drop, helper) {
var self = this;
self._executeDrop(drop, helper);
}
});
// Test cases
formeditortest.testDropSimple = function(assert) {
var container = $("<div />");
container.testcontainer();
container.testcontainer("drop", 0, 3);
assert.equal(true, $(innerDiv.children()[0]).hasClass("droparea"));
});
QUnit.test(name, function( assert ) {
formeditortest.testDropSimple(assert);
formeditortest.testDropBottom(assert);
});
Using this method the inherited testcontainer could have the preparation required to test elements and then the qunit will handle the test, this solves my problem, hope this works for someone else that is having troubles to approach these kind of tests.
Critics? welcome to comment, I want to improve this if I'm doing something silly!!!

Categories

Resources