I found 2 ways to define a global object using IIFE, like these:
(function () {
var func = function () { };
window.func = func;
}());
vs:
(function (myFunc) {
window.func = myFunc();
}(function () {
var func = function () { };
return func;
}));
I notice that almost js famous plugins use the second way, ex: jquery:
Why's that?
I think it's clearly a visual matter. UMD code may support multiple module patterns.
The second approach separates the UMD code from the module code. By opening the corresponding module file, one can see at the top, in one place, which module patterns are supported.
Related
Is it possible to override the global require function, affecting it at process level?
From what I know, the require function is provided as argument in the function that wraps the NodeJS scripts:
(function (..., require, __dirname) { // something like this
// The wrapped code
})(...);
Is there any way to modify the require function?
(function () {
var _require = require;
require = function () {
console.log("...");
_require.apply(this, arguments);
};
})();
This will probably affect only the script where it's located.
How can we modify it at the process level?
var Module = require('module');
var originalRequire = Module.prototype.require;
Module.prototype.require = function(){
//do your thing here
return originalRequire.apply(this, arguments);
};
mock-require does this by overriding Module._load (which is what the real require actually calls).
Here is a much safer native ES6 answer based on #orourkedd which acts like an event listener on all require calls, It might look like its replacing require but if you look closer its actually saying: require = require and trap calls to it but return original behaviour. This is just one of the millions of uses of Proxy() which has been really handy for me, for example in Typescript for mapping tsconfig "paths" with the real module node will resolve.
I would go as far as to say that this is not "Monkey patching" as its on a lower level of the language.
var Module = require('module');
Module.prototype.require = new Proxy(Module.prototype.require,{
apply(target, thisArg, argumentsList){
let name = argumentsList[0];
/*do stuff to ANY module here*/
if(/MyModule/g.test(name)){
/*do stuff to MY module*/
name = "resolveAnotherName"
}
return Reflect.apply(target, thisArg, argumentsList)
}
})
This is the workaround I found. If there is any better solution, I'm open to see it.
I created a script named req-modifier.js:
module.exports = function (_args) {
var _require = _args[1];
function newRequire () {
console.log("Require is called");
return _require.apply(this, arguments);
}
newRequire.__proto__ = _require;
_args[1] = newRequire;
};
Then from the files I want to modify the require function, I do:
require("./req-modifier")(arguments);
var foo = require("./foo");
The limitation is that I have to call every time the req-modifier function.
I see some code snippet as below while learning the Javascript, I am not sure about it, could you please advise what this structure exactly does, and when to use?
(function abc()
{
//action code here
})();
example
(function test() {
alert(1);
})();
Thank you much.
The best you can do is to read this article:
JavaScript Module Pattern: In-Depth
Smalle cite:
Anonymous Closures
This is the fundamental construct that makes it all possible, and really is the single best feature of JavaScript. We’ll simply create an anonymous function, and execute it immediately. All of the code that runs inside the function lives in a closure, which provides privacy and state throughout the lifetime of our application.
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
But really go through this article and observe what we do have, thanks to others, who described JS patterns for us...
Because the more imprtant piece is the MODULE pattern
Module Export
Sometimes you don’t just want to use globals, but you want to declare them. We can easily do this by exporting them, using the anonymous function’s return value. Doing so will complete the basic module pattern, so here’s a complete example:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
I see a lot of code here, here:
var module = (function (module) {
module.prototype.something_else = function () {
};
return module;
})(module);
Why var module = part present at all? And why return module; if previous part is not needed?
I see usage of:
var module = (function(module) {...})(module || {});
for cases when module wasn't already defined sometimes... Is that above case?
This block of code is only used if module is already defined and you want to extend it (e.g., add a new method):
var module = (function (module) {
module.prototype.something_else = function () {
};
return module;
})(module);
It accepts module as an input parameter and returns the extended module. The assignment of var module = then replaces the original module.
Answering your questions one by one:
Why var module = part present at all?
In the example above (taken from your first URL), var module = is not necessary. The simple example they provide is silly. You could accomplish the exact same thing with this:
module.prototype.something_else = function () {};
Using the above pattern to extend a class makes more sense with the examples provided in your second URL ( http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html ):
var MODULE = (function (my) {
var old_moduleMethod = my.moduleMethod;
my.moduleMethod = function () {
// method override, has access to old through old_moduleMethod...
};
return my;
}(MODULE));
Immediate executing function creates a new scope where we can preserve the old method var old_moduleMethod = my.moduleMethod;
Next question:
And why return module; if previous part is not needed?
You need return module because otherwise the function wouldn't return anything and the var module = assignment would be set to an undefined value.
Next question:
for cases when module wasn't already defined sometimes... Is that above case?
Yes, that is the case. If module isn't defined then you would need to pass in an empty object. However, you typically would use a pattern to extend an object if it isn't defined in the first place. That would make no sense and would just complicate your code.
To understand, it helps to rename identifiers to get the equivalent
var module = (function (module_impl) {
module_impl.prototype.something_else = function () {
};
return module_impl;
})(module || {});
module_impl is the object that is to hold the module's public API. So after populating it, the anonymous function returns it to the caller, which assigns it to the global module. This way the API is now available using module while any implementation details are hidden in the closure created by the anonymous function.
module || {} now is to allow augmentation: the first time it gets called, module is still undefined since the assignment to the return value of the anonymous function has not happened yet. Thus `module || {} evaluates to the second operand.
To further illustrate why the assignment is needed. The first time, the stub gets called, it is effectively the same as
var module = (function () {
var module_impl = {};
// ...
return module_impl;
})());
I'm looking to encapsulate my javascript inside a namespace like this:
MySpace = {
SomeGlobal : 1,
A: function () { ... },
B: function () { ....; MySpace.A(); .... },
C: function () { MySpace.SomeGlobal = 2;.... }
}
Now imagine that instead of a few lines of code, I have about 12K lines of javascript with hundreds of functions and about 60 globals. I already know how to convert my code into a namespace but I'm wondering if there's a quicker way of doing it than going down 12K lines of code and adding MySpace. all over the place.
Please let me know if there's a faster way of doing this.
Thanks for your suggestions.
I like to wrap up the namespace like so. The flexibility is huge, and we can even separate different modules of the MySpace namespace in separate wrappers if we wanted too. You will still have to add some sort of _self. reference infront of everything, but at least this way you can change the entire name of the namespace very quickly if need be.
You can see how with this method you can even call _self.anotherFunc() from the 1st module, and you'll get to the second one.
(function (MySpace, $, undefined) {
var _self = MySpace; // create a self-reference
_self.test = function () {
alert('we got here!');
_self.anotherFunc(); // testing to see if we can get the 2nd module
};
_self = MySpace; // reassign everything just incase
}(window.MySpace = window.MySpace || {}, jQuery));
$(function () {
MySpace.test(); // call module 1
MySpace.callOtherModule(); // call module 2
});
// Here we will create a seperate Module to the MySpace namespace
(function (MySpace, $, undefined) {
var _self = MySpace; // create a self-reference
_self.callOtherModule = function () {
alert('we called the 2nd module!');
};
_self.anotherFunc = function () {
alert('We got to anotherFunc from the first module, even by using _self.anotherFunc()!');
};
_self = MySpace; // reassign everything just incase
}(window.MySpace = window.MySpace || {}, jQuery));
jsFiddle DEMO
Wrap a function body around your existing code to use as scope, hiding everything from global - this will allow you to do internal calls without pasting Namespace. prefix everywhere, neatly hide things you don't want everyone else to see, and will require minimal changes as well.
After that, decide what functions you want to "export" for everyone and assign them to properties of object you want to use as "namespace".
I've got the first file in my code directory as follows
myNamespace.js
var myNamespace = {};
Then my subsequent files can look as one of the two following ways.
first
(function (ns) {
ns.DoStuff = function(){
// do stuff
}
})(myNamespace);
second
myNamespace.DoStuff = function(){
//do stuff
}
So what is the difference between these two methods? Both seem to work for me. Is there a more generally accepted convention?
sorry, still new to javascript
Your first approach will not work. It would create DoStuff on the global object (most likely window). You would need to replace this with ns, after you did that, there is no difference between the two approaches.
The former will have the adventage that you might be able to closure all your application/file related stuff into that outer self-invoking closure function. So you won't clobber the global namespace.
(function (ns) {
var foo = 10,
bar = 42;
ns.DoStuff = function(){
console.log('foo is ', foo, ' and its not available globally');
}
})(myNamespace);
You have an error in your first one, you've used this where I'm pretty sure you meant ns:
ns.DoStuff = function() {
};
Leaving that aside, your first approach tends to be better because you've created a nice little scoping function for yourself, which allows you to have private data and functions available to all of the public methods you create on your namespace, without making them globals. E.g.:
(function(ns) {
function privateFunction() {
}
ns.DoStuff = function() {
privateFunction(); // <=== works fine
};
})(myNamespace);]
privateFunction(); // <=== doesn't work, because it's private
I like doing it that way partially because I have thing against anonymous functions, and so I wouldn't define DoStuff as above, but rather like this:
(function(ns) {
ns.DoStuff = Namespace$DoStuff;
function Namespace$DoStuff() {
}
})(myNamespace);
Now the function I've assigned to myNamespace.DoStuff has a proper name, which helps me out when I'm debugging my code. But that name doesn't pollute the global namespace, which helps me stay sane and avoid conflicts with other code.