Can you or should you use delegates (function pointers)? - javascript

This might be basic, but since I am new to this I cant understand if I am doing it wrong- and its a bad practice. Say I have 3 JS files :
a.js
b.js
sdk.js
say that sdk.js is some SDK, and I would like to call functions inside it, from different js files, such as a or b.
Is the way to go is to just call functions in sdk.js from any other file directly ? this seems like no capsulation to me but I couldn't find another way without having object oriented programming.

There are several ways to call functions in another file.
1) Native Solution
In your HTML file, make sure your <script> tag importing sdk.js is loaded first, like so
<script src="./sdk.js/"></script>
<script src="./a.js/"></script>
<script src="./b.js/"></script>
As long as sdk.js declares the function in the global namespace, any file loaded afterwords should have access to it
2) ES6
If you can use ES6 features (via babel or webpack, for example), then your other scripts can import the file. Take the following example:
sdk.js:
export var foo = function(){
return "foo";
}
a.js
import foo from "./sdk.js";
foo();
3) Node.js way
Node.js supports require, another way of importing files. These files would operate under their own scope, and you would have to use module exports to make a function or variable "public".
** Worth nothing that this only works in node, not the browser, however
4) Require.js way
You can use the require.js library to import other files as well.
Additional Resources
This SO Question has far more in-depth answers than what I've outlined above. Best of luck!

Can use
module.exports = {
a:()=>{
console.log("This is 'a' function");
},
b:()=>{
console.log("This is 'b' function");
}
}
you can call those functions from next file by importing above file by
const file1 = require('that_file_name');
file1.a();
file1.b();
Hope you got the right answer.

Related

JavaScript namespaced modules in single file VS import/export loaded modules (e.g. requireJS, es6)

I'm trying to figure the most efficient way to structure modules in our website that contains a lot of JavaScript namespaced modules in a single file (app.js) already.
Currently things look a bit like this:
app.js
OURAPP.mapsModule = (function() {
return ...
})();
...
OURAPP.searchModule = (function() {
return ...
})();
..and these are all contained within a single file. So, when we want to use any of these modules we:
search-page.js
...
OURAPP.searchModule.search(query);
...
search.html
...
<script src="js/main.js">
<script src="js/search-page.js">
...
We do have a lot of such modules. However, I'm wondering whether we should be doing something with import/export modules:
Method #2
searchModule.js
export default {
...
}
search-page.js
import searchModule from "./js/searchModule";
...
searchModule.search(query);
...
I'm guessing that a single file namespaced modules will be faster for the page to load(?) as it's only a single file to download. But when I'm looking at testing frameworks (e.g. Jest) they give many examples where module script files are loaded in this manner. Does it lend itself better to testing I'm wondering? Personally, I prefer this structure anyway but it's a bold change of direction from how the site has been built up until now and I'll need to good reason to suggest this. This website's is pretty much all generated server-side with JavaScript just doing the show/hide, query APIs, etc, with the addition on scrips and JavaScript libraries such as jQuery, Bootstrap, Isotope when required on each page.
I've read around but can't find anything comparing exactly both methods here and reasons for and against either. Would appreciate any suggestions or helpful advice, thanks.
Don't default-export objects, use named exports instead:
// searchModule.js
export function search(…) {
…
}
// search-page.js
import * as searchModule from "./js/searchModule";
…
searchModule.search(query);
…
I'm guessing that a single file namespaced modules will be faster for the page to load as it's only a single file to download.
Yes, that's true. However, do not let that affect your decision on how to structure your modules. You should always modularise your code so that it is the cleanest possible. Put the maps stuff in a different module than the search stuff.
You will then use a bundler or packer tool to create a single minified JS file to download that contains all the modules that the respective page needs.

How to create and implement a custom JavaScript library

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.

Module pattern defined in separate files

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.

Equivalent of C extern declaration in JavaScript

Writing some JS and would love to enumerate specifically what I'm importing from other files in the main body of my JS script. Is there an equivalent to C's extern declaration for JS?
Thanks!
Variables declared outside of function scope are global in JavaScript. For example, if you have two JS files and declare a variable 'myObject' in the first file, it will be in scope for the second file, and declared for use if the first file is loaded into the browser already.
If you need access to objects between JS files, it's good practice to expose one object to the global namespace and declare fields and methods on that object.
File 1:
var myObject;
myObject.myField = "Field!";
File 2:
myObject.prototype.myFunction = function () {
return this.myField;
};
Hope this helps, happy to hear other suggestions and open to corrections :D
There's no equivalent to a C extern declaration in JavaScript because JavaScript doesn't require variables to be declared before they're used the way C does.
If your JavaScript code depends on some properties being defined on the window object, just document those properties in a comment near the top of the file.
Sadly, Javascript has no built in features for controlling what gets imported or not.
By default, all sripts loaded in a page will write their global variables to the same shared global scope. The only way around this is writing your scripts so that they create as few global variables as possible, using the module pattern.
Alternatively you can use one of the module systems extensions that people came up with. For example you can write your scripts using the CommonJS module system and it will make it make it so that top level var declarations in your scripts arent seen from other scripts and lets you explicitly export the values you like. Some runtimes like nodejs can run CommonJS modules natively and for the ones that dont, like browsers, you can use a tool like browserify to compile the commonjs modules into a single file that can be put into a script tag and that will still do the right thing.

Meteor and javascript: make functions in one file available to another

I use iron-router with Meteor and I have written a number of functions that I call from the Router.map() which defines all my routes and hooks. The file is getting to be cumbersome to scroll around in and I would like to move my functions to a different file.
The only way I've found to make functions in one file available to those in another file is to define those functions in a script tag inside the head tag. But of course, I'd rather not put them there. I assume there's a straightforward way to do this?
You create the functions the following way?
function myFunction(){
// Your code...
}
This creates a local variable storing your function (all code in each js-file is wrapped in a function!). You must instead store your function in a global variable, which can be done in the following way:
myFunction = function(){
// Your code...
}
Create a folder named "lib" in your project. Then create functions.js in the lib directory and put there all your functions.
See http://docs.meteor.com/#structuringyourapp

Categories