I am new to javaScript and am unsure how to go about creating a new js library and referencing this in another js file.
If I have a standalone file Utilities.js
var Utilities=
{
show: function(input)
{
alert(input);
}
};
Am I missing something as to how a library should be defined standalone?
My second question is how to use that is sub-sequent js files. What I did so far is:
<script type="text/javascript" src="resources/Utilities.js"></script>
In my index.html. Is this enough to reference it as:
Utilities.show("Hello");
In any other java script file?
I tested it in this fashion and got and error "Utilities is not defined"
NOTE: This is just an example and not my full and practical purpose.
Yes, including that Javascript file with that global variable declared is enough to call your methods this way Utilities.show("Hello"); from another Javascript file loaded after Utilities.js or inside a <script></script> section of your html.
But you can actually improve it a little, following the module pattern and exposing only the functions you really need to the global scope (you'll likely write some functions that the users of your library should not call directly, this allows you to do it in a clean way):
var Utilities=Utilities||(function () {
//Accessible only here
var privateArray=[];
//Cannot be called from outside this function
var privateFunction=function(){
}
//Return only what must be publicly accessible, in this
//case only the show() method
return {
show: function(input){
privateFunction();
alert(input);
}
}
})();
That (function () { /* Code */})();, defining a new scope for your code will also avoid name clashes with other global javascript object/functions.
It is OK to use object literals, but you can define libraries using other patterns (module, revealing module, constructors, etc).
I recommend these links to understand primitives, scopes, closures, object literals, etc.
http://bonsaiden.github.io/JavaScript-Garden/
http://jsbooks.revolunet.com/
To call the method inside index.html you need to add a tag.
<script>
Utilities.show("Hello");
</script>
But this approach it's not recommended. Instead of it, you can create a new JS file to run your library code.
<script type="text/javascript" src="resources/Utilities.js"></script>
<script type="text/javascript" src="resources/main.js"></script>
In main.js
Utilities.show("Hello");
Hope it helps.
Given the fact that you gave, within yout question, zero context of what you're trying to achieve, the best answer to your original question is that it depends.
If you just need a bunch of files and you're done (like in your example, Utilities.js and a few more) then you're ok with the way you're heading to.
But of course, you'll allways want to scale your front end and thus you should adhere to some architectural pattern. So, if you're building a client side (browser-side) application, then you should really implement your libraries using the module pattern, and begin your project from a good project example / scaffold.
On the other hand, if you're rendering the html on server (e.g. you're using PHP to render the final html file that will be sent to browser) and you just need some thin functionality in the browser, the way you begun can be okay if you're careful. Also, you can still implement the module pattern here too, although I strongly suggest that you should make use of namespacing to have a clear separation of concerns.
In browser based javascript you can't just call functions from different files yet. In Es6 there are ways. But not yet. Which mean just because you have some variable or function etc then you cant reference it automatically in another file.
Unless both files are loaded into one html and are loaded in order.
Alternatively you could run task runner like grunt and 'merge' them upon each build.
Javascript doesnt have special concept of library, in es6 it's a little different, everything is an object.
What you are doing is just creating an object. and yes it will work.
Related
Is there a convenient approach to code organization, which allows to create a module pattern, but define its internally exposed functionality in separate files.
So, with a module below, can SomeInternalObject2 be defined in another js file and still be accessible from the first file (assuming proper ordering of script files)?
var MyModule = (function(){
function SomeInternalObject1(){..}
function SomeInternalObject2(){..}
return {
this.publicFunction = function(){..}
}
})();
EDIT: Perhaps I'm thinking about it in a wrong way. Code organization is a development-time concern. Require.js, module-loading, etc.. is a run-time concern.
Have look at jTable (javascript). The author augments the main object from different files. It is not exactly what you are asking for, but the intention or goal seems similar. I might add code later.
I'm using the latest qooxdoo SDK (3.5) and am trying to find a way to dynamically load a module. Each module would implement an "init" function which creates a window in the application and, from that point, is self-contained.
What I would need is the ability to call an arbitrary init function without knowing the module existed beforehand. For example, someone uploads a custom module and tries to run it--I just need to call the module's init function (or error out if the call fails).
Any ideas?
Edit:
Something like:
function loadModule(modName) {
var mod = new qx.something.loadModule(modName);
mod.init();
}
I found 3 ways that Qooxdoo has to run dynamic code. The first way is via the built-in parts loader. "Parts" are basically portions of an application that qooxdoo will load "just-in-time" when you actually need them--for example, a class that operates a rarely used form or dialog box. This method is not truly dynamic (in my opinion) in that it requires the code to be included in the build process that Qooxdoo provides. Explaining exactly how it works is out of scope for this answer and, frankly, I'm not yet all that familiar with it myself.
The second way is via the qx.Class.getByName() function call. It works like so:
qx.Class.define("Bacon", {
extend: qx.core.Object,
construct: function(foo, bar) {
this.foo = foo;
this.bar = bar;
}
});
var klass = qx.Class.getByName("Bacon");
var obj = new klass("foo", "bar");
this.debug(obj.foo);
This method was found on the Qooxdoo mailing list here. This method will work for code included in the build process and for code introduced dynamically but, in my opinion, is trumped by the third method for the simple reason that if you are introducing a new class dynamically, you'll have to use the third method anyway.
The final method I located was actually revealed to me via studying the source code for the Qooxdoo playground. (The source code is available as part of the desktop download.)
The playground reads the code in from the editor and creates an anonymous function out of it, then executes the function. There is a bunch of setup and tear-down the playground does surrounding the following code, but I've removed it for brevity and clarity. If you are interested in doing something similar yourself, I highly recommend viewing the source code for the playground application. The dynamic code execution is contained within the __updatePlayground function starting on line 810 (Qooxdoo v3.5).
var fun;
try {
fun = qx.event.GlobalError.observeMethod(new Function(code));
} catch(ex) {
//do something with the exception
}
try {
fun.call();
} catch(ex) {
//do something with the exception
}
The code is straightforward and uses the built-in Javascript function "call" to execute the anonymous function.
Please define module.
Qooxdoo source code uses the same convention as Java - one class per file. Do you really want to load classes individually and deal with dependencies? If not, what's your definition of a module?
Other than that, qooxdoo has a notion of packages, which are groups of classes, interfaces and mixins, framework, contribs, including the framework itself, packed by the generator in an optimized way, so that the classes used earlier are loaded earlier. Using qooxdoo's own packaging mechanism requires no more effort than running build with custom arguments or customizing the config.json - all described in detail in the manual.
If your idea of a module is sort of a sub-application, mostly decoupled from everything else in the big application, I'm not sure it's achievable without either significantly modifying the generator code (what ./generate.py calls) or accepting some size overhead.
I won't go into details of modifying the generator - if you go this route you'll need to dig deeply anyway, and you'll learn more than I know about the generator.
What you can do while staying within what qooxdoo allows is to create a separate island application for each module, build your own infrastructure for inter-modules communication via JavaScript attached to the top window, and run the modules inside the main page, with some manually added magic to make the various modules behave like tab panes or qooxdoo windows. The overhead you'll have to take, besides some awkward custom, non-qooxdoo code, is that all modules will re-load the qooxdoo framework code.
I'm trying to experiment with [this library](https://code.google.com/p/autotags/ in meteor).
First, when I tried to install all the individual javascript files to client/compatibility folder, I get an error message when calling AUTOTAGS from the constants js file:
AUTOTAGS = { ... } // autotags-js-core.js
AUTOTAGS.TAG_CONSTANTS = [ 'news','research','favourite' ]; // autotags-js-constants.js
It kept saying that AUTOTAGS was undefined. I deduced from reading about global scope that any external library with VAR that you want to have global scope, put it under compatibility.
If that's correct, then why isnt the scope global when putting all individual files under lib/external? AUTOTAGS = {..} without var means its available to entire application right?
Instead, I got the scope to work by combining all the javascript files in one single js file under lib/external. I thought I understood, but it gets worse.
Within a single js file - any function that begins with a closure is local to that FILE, and not global scope, whilst any function assigned to variable name makes it a global variable?
function(something() { ... } ) // closure, local
generateTags = function() { ... } // global scope?
var generateTags = function() { .... } // is this local or global?
If the var generateTags function is local, then putting it under client/compatibility will make it global? Lastly! - I get the vague notion that I should define global variables under lib/environment.js from here - https://github.com/oortcloud/unofficial-meteor-faq#where-should-i-put-my-files, is that true?
There are actually two questions here. One is about how the scope works in javascript, the other about integrating the autotags library into a meteor project. Since the answer for the first one should be relatively easy to find somewhere else, I'll only try to answer the second question.
The reason you are getting this "undefined" error is not a scope problem but it is somehow related to the order in which the files are loaded into your meteor app. Namely, autotags-js-constants.js comes before autotag-js-core.js because constants precedes core in the alphabetic ordering. In consequence, the AUTOTAGS variable is not defined at the point when the autotags-js-constants.js file is being parsed.
One simple way to overcome this issue is to rename your files, so as to enforce the right loading order. Another way is to use a tool that will enable you to define dependencies between files. If you are interested please take a look at require project, which is basically a lightweight and meteor friendly implementation of the core requirejs features.
However, probably the best solution is to create a custom smart package. It would allow you to explicitly define the order in which the files should be loaded. Just take a look on some existing smart packages to get the idea on how this should be implemented. I would also recommend using meteorite to manage your custom smart packages.
Not really sure how to ask this, but I'm just looking for some insight/info.
If I'm including multiple JavaScript files in my app, how does the page/app see all the JS code. Does all the JS in all files become one-big JS file
If one JS file has a variable foo=true; and another JS file has foo=false, what is the scope of foo? Is it local to the script it is in or does it become seen in 'all' the js code?
Thanks for any insights.
Yes, for most purposes it's just like if there were only one file, built by concatenating all the files in the order of imports.
The differences :
"use strict"; (supposing it's present) is only valid per file
it's much slower for the browser to fetch 10 small files than a big one, which is why js developers building big applications usually concatenate (and often minify) all the files for production
The only thing the scripts share is the global scope; the separate parts don’t become one big file.
For example, you can’t do this:
<script type="text/javascript">
function hello() {
</script>
<script type="text/javascript">
}
</script>
And a 'use strict' in one <script> wouldn’t apply strict mode across all of them.
If you define in one file, without using var:
foo = true;
It will be a global variable, and it will be accessible by your second JS file when it does foo = false
All your scripts will share the same global namespace if they are defined in plainly on the page. To create a local scope for your variable, you'd have to wrap it in a function.
See the explanation provided in this question: What is the scope of variables in JavaScript?
To easily handle multiple JavaScript files and keeping the global scope minimal, while allowing the different scripts to share information, I recommend you try RequireJS (http://requirejs.org/), it is a JavaScript file and module loader. It will handle any file dependancies you may have and it'll load them asynchronously. It will also make it easy for you to pass variables amongst the different modules/files without having to expose them to the global scope.
There are other file/module loaders too. See: http://www.netmagazine.com/features/essential-javascript-top-five-script-loaders
I've spent a great deal of time creating and testing an application with quite a few functions. Now that I have configured everything and it works how I want, I would like to begin cleaning up the code so its not 400 lines of mush.
I have already created an external CSS file and would like to do something similar for the JS and possibly even the HTML (approx 100 lines of code of just HTML, ick).
Admittedly I am a novice programmer but I've picked up quite a bit of knowledge in the short time I've been doing this. What is the best way to separate out the functions into external files and then call them so that the whole application works as it does now?
For example (this is a web mapping application): I have functions for search, basemap gallery, legend, layers, init, infowindows, etc. Since the code is already written and I'll be creating multiple applications in the future, the goal would be to just have these js functions in files ready to be referenced by whatever application needs them.
Thanks.
To link an external javascript file, place a script tag with a src attribute pointing to your file.
<script src="legend.js"></script>
<script src="layers.js"></script>
<script src="init.js"></script>
Calling a function requires nothing special.
onclick="myFunction();"
Could you not just put all of those functions in one .js file and then call the file from within your web page?
<script src="../scripts/javascript.js"></script>
And then call on your functions as and when you need them?
The first thing you might consider doing do is to create a non-global "namespace" for your functions in a fashion such as the following:
window.MyApp = window.MyApp || {};
The above line can be at the top of every file; the first time it is invoked it creates a new namespace/object, subsequently it returns the one you previously created.
Then you can move your functions under MyApp in a manner such as the following:
MyApp.func1 = function() {...}
Google for creating Javascript namespaces, and possibly also the Javascript module pattern