What are the arguments to this javascript factory assigned to? - javascript

I am trying to understand how this JavaScript pattern works it is an entire library enclosed in parenthesis. My understanding is that the parenthesis are a way to scope variables, but inside is a single function that takes the argument (global, factory).
I've tried searching for how this pattern works but cannot find anything.
The body of code returns an object that can be used elsewhere, but I don't understand what the purpose of the arguments global and factory accomplish.
I have been reading about enclosures and anonymous functions, but can't find anything about an enclosure defined like this.
(function (global, factory) {
global.className = factory();
} (this, function () {
ObjectName.prototype = function() {
/* some code */
}
var data = {
getUsefulData: function(obj) {
return new ObjectName(obj, 'usefuldata');
}
}
return data;
})
);
Questions:
what would happen if the outer function had no arguments?
what value gets assigned here to the global and variables?

What you're seeing, is an IIFE (an Immediately Invoked Function Expression) with two parameters. Consider this example:
const x = (function(a, b) { return a + b; })(5, 6); // x === 11
The parameter global gets assigned the argument of this (which, when used at the top level, is a universal way of reaching the global object, window for browsers and global for Node.js), the second parameter factory gets assigned the big (second) function.
The IIFE then puts the result of the factory function (which is actually the library code) onto the global object under the className key (also known as a namespace in this pattern).
This is a variation on the Revealing Module Pattern, only what's returned from the factory function will be placed on global.className, allowing you to have "private" variables and functions that will not be exposed, but are still accessible to the "public" objects.
(function(global, factory) {
global.myModule = factory();
}(this, function() {
const privateMessage = 'secret';
function secret() {
return privateMessage;
}
function open() {
return 'Message: ' + secret();
}
return { open };
}));
window.myModule.open(); // Message: secret
// no way to directly access privateMessage or secret().

Related

Javascript Is it possible to declare functions in a return?

According to this article (https://www.intertech.com/Blog/encapsulation-in-javascript/) the following code is an example of encapsulation in JS. What it does is basically restrict the possibility of modifying the variable fullName, so only if the new fullName does not have numbers it can be changed.
var person = (function () {
var fullName = "Jason Shapiro";
var reg = new RegExp(/\d+/);
return {
setFullName : function (newValue) {
if( reg.test(newValue) ) {
alert("Invalid Name");
}
else {
fullName = newValue;
}
},
getFullName : function () {
return fullName;
}
}; // end of the return
}());
alert(person.getFullName()); // Jim White is printed again.
person.setFullName( 42 ); // Invalid Name; the name is not changed
It all seems logic to me, but what I haven't been able to get is how can he call either getFullName or setFullName, if these functions are in the return block.
There is nothing too surprising about this example; we just have to break it down.
A variable called person is being declared.
What kind of object is person? Well, it is the result of calling an anonymous function on zero arguments.
When that anonymous function is called, it returns an object.
The object returned by the function has two properties, setFullName and getFullName.
The object returned by the function is the value of variable person. Therefore person.getFullName and person.setFullName are both valid expressions.
I think the point of confusion may be that you thought the scope of getFullName and setFullName is restricted to code inside the return expression. However, JavaScript is a very dynamic language. Properties can be added to and removed from an object at any time. And it is at run time, not compile time, where the JavaScript interpreter checks for the existence of properties.
Because the object person is being initialized with something called Self-invoking functions:
(function () {
// body of the function
}());
The anonymous function above will be invoked right after it has been defined. The benefit of self-invoking functions is that they enable us to execute code once without cluttering the global namespace (without declaring any globals). Reference
Therefore, your object right in that moment is being initialized with the returned value.
In your case, with:
{
setFullName: function(newValue) {
if (reg.test(newValue)) {
alert("Invalid Name");
} else {
fullName = newValue;
}
},
getFullName: function() {
return fullName;
}
};
So, the object person will be initialized with those functions and for that reason you will be able to call getFullName and setFullName.
In person variable we have an IIFE (immediately invoked function expression), which executes immediately, when the interpreter reaches this line. And this function returns an object, so finally, person variable is an object, and as we know, objects can contain functions too, and we can easily invoke functions from this object like so:
person.getFullName();
person.setFullName(42);
I think what you're not noticing in the code is its form: a function is declared and immediately run. The value stored in person is not a function, but an object containing two functions.
function () { ... } is a function.
(function () { ... )()) is the return value of that function.

What is a "scoping function" in javascript?

In Learning Javascript Design Patterns, the author says
Object literals don't require instantiation using the new operator but
shouldn't be used at the start of a statement as the opening { may be
interpreted as the beginning of a block. Outside of an object, new
members may be added to it using assignment as follows
myModule.property = "someValue";
Below we can see a more complete example of a module defined using
object literal notation:
var myModule = {
myProperty: "someValue",
// object literals can contain properties and methods.
// e.g we can define a further object for module configuration:
myConfig: {
useCaching: true,
language: "en"
},
// a very basic method
saySomething: function () {
console.log( "Where in the world is Paul Irish today?" );
},
// output a value based on the current configuration
reportMyConfig: function () {
console.log( "Caching is: " + ( this.myConfig.useCaching ? "enabled" : "disabled") );
},
// override the current configuration
updateMyConfig: function( newConfig ) {
if ( typeof newConfig === "object" ) {
this.myConfig = newConfig;
console.log( this.myConfig.language );
}
}
};
// Outputs: Where in the world is Paul Irish today?
myModule.saySomething();
// Outputs: Caching is: enabled
myModule.reportMyConfig();
// Outputs: fr
myModule.updateMyConfig({
language: "fr",
useCaching: false
});
// Outputs: Caching is: disabled
myModule.reportMyConfig();
Using object literals can assist in encapsulating and organizing your
code and Rebecca Murphey has previously written about this topic in
depth should you wish to read into object literals further.
That said, if we're opting for this technique, we may be equally as
interested in the Module pattern. It still uses object literals but
only as the return value from a scoping function.
My Question:
What does he mean by "It still uses object literals but only as the return value from a scoping function."
Specifically what is a "scoping function"?
In JavaScript, variables declared with var are "function scoped" not "block scoped" like in other C-like languages (and how the {} syntax might imply). (Update Re: block scoping: ES6 introduced block scoping with two new variable declarations, let and const. See https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/)
To create a module with a "scoping function" means to use a function to wrap the scope of variables and other logic you may use, and then return an object literal with the results you want.
Example:
function personFacory(name) {
var person = {
name: name
};
if (name === 'Bob') {
person.isBob = true;
}
return person;
}
The case of the IIFE and closure #Josh mentions is also a valuable use of a "scoping function."
Another example:
var generateId = (function(){
var currentId = 0;
return function() {
return currentId++;
};
})();
Each time you call generateId(), it will return the next integer.
Pretty sure it's referring to an immediately invoked function expression, so that all the data present in the module is "scoped" (private, not affecting the global scope, whatever you wanna call it):
var somethingInTheGlobalScope = true;
var myModule = (function() {
var somethingThatOnlyExistsHere = true;
return {
myModuleMethod1: function() {},
myModuleMethod2: function() {}
}
})();
This IIFE is almost equivalent to just writing out a module in object literal notation, except with this pattern, you get the benefit of scopes not colliding with each other (i.e., any scope outside of your IIFE stays separate from the scope within the IIFE).
Note from Addy Osmani:
The Module pattern encapsulates "privacy", state and organization using closures.
Well in javascript we have a thing called function scope which means that the variable declared within a function are visible only within that function, more on scopes and hoisting here https://www.digitalocean.com/community/tutorials/understanding-variables-scope-hoisting-in-javascript Before ES6 the only way to create modules with isolated functions and variables from the global scope so they cannot override already existing functions and variables with the same names was to wrap the functionality you want to isolate in an IIFE (Immediately Invoked Function Expression) https://developer.mozilla.org/en-US/docs/Glossary/IIFE. These are functions that run as soon as they are defined and create an isolated scope of variable and function that isn't visible to the "outside world" or said otherwise the global scope i.e.
function sayHello() {
var name = "Viktor"
var personModule = (function() { //Here we define our IIFE
var name = "Adam";
return { //Here we return an object literal with a scoping function
sayHello: function() {
console.log("Hello my name is " + name);
}
}
}())
personModule.sayHello() //This will print "Hello my name is Adam"
console.log("Hello my name is " + name) //This will print "Hello my name is Viktor"
}
sayHello();
In the sample above first we define a sayHello function in the global scope and after that in it we define an IIFE that returns an object literal with the function sayHello in it and assign it to a variable called personModule. The function personModule.sayHello creates a closure because it holds a reference to the name variable of the IIFE scope. The IIFE is already executed but the function scope of the IIFE function remains in memory and it isn't collected by the garbage collector because the personModule.sayHello function will be executed outside the lexical scope where the function is defined and the reference to the name variable keeps this function scope alive. Said in other words personModule.sayHello keeps a reference to the surrounding state where the function is defined and this behavior is called a closure context https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures. At the end, we have to name variables one with the value "Viktor" that is defined in the global sayHello function's scope and one with the value "Adam" that lives in IIEF function scope and it is not visible to the outer scopes including the global scope. The only way to access this variable is through personModule.sayHello. This way the one name variable does not override the other name variable and both variables exist with different values in different scopes.

what is self-executing anonymous function or what is this code doing?

var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"
Can anyone help me understand what's going on here? I get that if you call notGlobalFunction(), it will just call the second function.
But what is var module = {} doing? and why is it called again inside the first function?
It says this is commonly known as a self-executing anonymous function but I don't really know what that means.
Immediately invoked functions are typically used to create a local function scope that is private and cannot be accessed from the outside world and can define it's own local symbols without affecting the outside world. It's often a good practice, but in this particular case, I don't see that it creates any benefit other than a few more lines of code because it isn't used for anything.
This piece of code:
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
Would be identical to a piece of code without the immediate invocation like this:
module.notGlobalFunction = function() {
console.log('I am not global');
};
The one thing that is different is that in the first, an alias for modules called exports is created which is local to the immediately invoked function block. But, then nothing unique is done with the alias and the code could just as well have used modules directly.
The variable modules is created to be a single global parent object that can then hold many other global variables as properties. This is often called a "namespace". This is generally a good design pattern because it minimizes the number of top-level global variables that might conflict with other pieces of code used in the same project/page.
So rather than make multiple top level variables like this:
var x, y, z;
One could make a single top level variable like this:
var modules = {};
And, then attach all the other globals to it as properties:
modules.x = 5;
modules.y = 10;
modules.z = 0;
This way, while there are still multiple global variables, there is only one top-level global that might conflict with other pieces of code.
Similarly, an immediately invoked function creates a local, private scope where variables can be created that are local to that scope and cannot interfere with other pieces of code:
(function() {
var x, y, z;
// variables x, y and z are available to any code inside this immediately invoked function
// and they act like global variables inside this function block and
// there values will persist for the lifetime of the program
// But, they are not truly global and will not interfere with any other global
// variables and cannot be accessed by code outside this block.
// They create both privacy and isolation, yet work just as well
})();
Passing an argument into the immediately invoked function is just a way to pass a value into the immediately invoked function's scope that will have it's own local symbol:
(function(exports) {
// creates a local symbol in this function block called exports
// that is assigned an initial value of module
})(module);
This creates a new empty object:
var module = {};
It does the same as:
var module = new Object();
This wrapper:
(function(exports){
...
}(module));
only accomplishes to add an alias for the variable module inside the function. As there is no local variables or functions inside that anonymous function, you could do the same without it:
module.notGlobalFunction = function() {
console.log('I am not global');
};
An anonymous function like that could for example be used to create a private variable:
(function(exports){
var s = 'I am not global';
exports.notGlobalFunction = function() {
console.log(s);
};
}(module));
Now the method notGlobalFunction added to the module object can access the variable s, but no other code can reach it.
The IIFE is adding a method to the module object that is being passed in as a parameter. The code is demonstrating that functions create scope. Methods with the same name are being added to a object and the the head object (window) of the browser.
"self-executing" might be misleading. It is an anonymous function expression, that is not assigned or or given as an argument to something, but that called. Read here on Immediately-Invoked Function Expression (IIFE).
what is var module = {} doing?
It initializes an empty object that is acting as a namespace.
why is it called again inside the fist function?
It is not "called", and not "inside" the first function. The object is given as an argument ("exports") to the IEFE, and inside there is a property assigned to it.

Some function notations in JavaScript with jQuery

I have a question regarding syntax that I've been coming across in JavaScript.
What does it mean if I define functions or variables inside a context like the one just below?
(source: http://tutorialzine.com/2010/12/better-confirm-box-jquery-css3/)
(function($) {
$.confirm = function() {
...
}
$.confirm.hide = function() {
...
}
})(jQuery);
Also, what the $. mean in the function $.confirm? Also, with $.confirm.hide, I feel that there is some jQuery object involved.
What does it mean if I define functions or variables inside a context like the one just below?
It means that you've defined a function, and ideally prevented global pollution (unfortunately, it wont actually help against global warming). There's a lot going on, so I'll try to split it out into a few parts:
(function($) {
$.confirm = function() {
...
}
$.confirm.hide = function() {
...
}
})(jQuery);
Part 1 - Closure
JavaScript is not like most other C-style languages, blocks1 do not get a new variable scope. In many C-style languages, a variable defined within a block will only exist within that block:
Some other C-style pseudo-code
function foo() {
var a = 1;
if (somecondition) {
var b = 2;
output(a, b); //1, 2
}
output(a, b); //throws some sort of exception because 'b' isn't defined.
}
JavaScript:
function foo() {
var a = 1;
if (somecondition) {
var b = 2;
output(a, b); //1, 2
}
output(a, b); //1, 2 due to variable hoisting
}
In JavaScript, variables don't have block scope, instead they have functional scope. Any defined variable is owned by it's first function ancestor. The instantiation of the variable is moved to the top of the function when the script is analyzed (this is called "variable hoisting"), so although you may have written foo (as seen above), what it's actually interpreted as is as follows:
function foo() {
var a, b;
a = 1;
if (somecondition) {
b = 2;
output(a, b);
}
output(a, b);
}
If there is no parent function of the variable, it's added to the global object, which in web browsers is window:
<script>
var a = 1;
output(window.a); //1 - set because there's no parent function
</script>
functions declared using function [some name]() {...} are treated similarly.
<script>
function foo() {return 1;}
output(window.foo()); //1
</script>
If you work on a large project and all variables are defined without a parent function, multiple programmers might use var foo, and would overwrite window.foo, which would lead to buggy and unstable code.
JavaScript allows for the creation of self-executing anonymous functions:
( function (){} )();
-or-
( function () {}() );
This is useful because it creates a new function context with which variables and functions can be defined without polluting the global namespace2. Functions like this that close over a set of variables/functions are called closures.
Parameters can be defined just like any other function, and they are passed to the function in the last set of parens. This explains your first and last lines of code:
(function ($) {
...
}(jQuery));
A new function context is created, and jQuery is being passed into the context into the variable $. This is used for aliasing jQuery to the shortcut $, which is a valid character for variable and function names.
Part 2 - Everything's an Object
Everything in JavaScript is an object, except for null and undefined. Mutable objects can have properties and methods set on them. Object literals ({}), array literals ([]), functions (function(){}), and objects created using constructors (new String('foo')) are all mutable objects.
var a = {};
a.foo = 'bar';
function b() {}
b.fizz = 'buzz';
This means that the jQuery object, which is a function, and has been aliased to $, can have new properties added to it:
$.confirm = function () {...};
And after the new $.confirm function is created, $.confirm is an object that can have properties added to it:
$.confirm.hide = function () {...};
If you wanted to call the confirm function outside of the closure, you'd write:
jQuery.confirm();
If you wanted to call the hide function outside of the closure, you'd write:
jQuery.confirm.hide();
1: a block is a section of code contained within {} characters, such as if (...) {/* block region */}, switch() {}, function () {}, while () {}, etc. Don't confuse object literals, which instantiate new objects, with blocks.
2: global namespace pollution is simply adding too many new variables on the global object, which is typically window
By wrapping a function in parens then executed using to more parents (function() {])(); is a n immediately invoked function. By passing in jQuery within the 2nd set of parens you pass in a paramter which you are you passing in as $.
$.confirm is just a method of the jQuery object
(function($) { // $ = jQuery
$.confirm = function() { // <-- set method of jQuery
...
}
$.confirm.hide = function() { // <-- set method of confirm
...
}
// usage
$.confirm();
// or
jQuery.confirm();
})(jQuery); // pass in the jQuery object to the function via immediate invocation
Many libraries, like jQuery, use $ as a shortcut variable because it stands out from typical variables used in javascript.
The code creates an anonymous function and calls it with jQuery as the argument. It's the same as
function addProperties($) {
$.confirm = function() {
...
}
$.confirm.hide = function() {
...
}
}
addProperties(jQuery);
$ is a valid variable name in javascript, and the function is adding properties to it. It's the same as:
function addProperties(j) {
j.confirm = function() {
...
}
j.confirm.hide = function() {
...
}
}
addProperties(jQuery);
jQuery is an object, and using the dot operator accesses its properties. For example, an object of apple might look like:
var apple = {
color: 'red',
height: 55,
foodType: 'fruit'
};
alert(apple.foodType); // alerts 'fruit'
You might have some misconceptions about jQuery based on your question. jQuery isn't a feature of javascript, it's a library of code that creates a large object called jQuery, though it can also be accessed as $.
The $ is the name of the parameter to the function that is used to create the scope, and because it's called with the jQuery object, $ will be equal to jQuery inside the scope. (By default the global name $ is also assigned jQuery, but this way of using a scope enables you to use $ inside it even if jQUery is used in compatibility mode, where the global $ identifier is not set.)
So, assigning a function to $.confirm will in effect assign it to jQuery.confirm.
As functions are objects in Javascript, you can add properties to them. That's why you can assign a function to $.confirm.hide, which is of course jQuery.confirm.hide.
After that code has run, you can call the jQuery.confirm function, and the jQuery.confirm.hide function.

Javascript closure

The following program returns "local" and, according to the tutorial Im reading, it is designed to demonstrate the phenomenon ofclosure`
What I don`t understand is why, at the end, in order to call parentfunction, it assigns it to the variable "child" and then calls "child."
Why doesn`t it work by just writing parentFunction(); at the end?
var variable = "top-level";
function parentFunction() {
var variable = "local";
function childFunction() {
print(variable);
}
return childFunction;
}
var child = parentFunction();
child();
parentFunction() returns another function which you assign to var child. Then, you call child() to invoke the function returned by the call to parentFunction().
Running just parentFunction(); at the end wouldn't do anything useful because you would just discard its return value which is a function. But this would work:
parentFunction()();
See this fiddle: http://jsfiddle.net/USCjn/
Update: A simpler example:
function outer() { // outer function returns a function
return function() {
alert('inner function called');
}
}
x = outer(); // what is now in x? the inner function
// this is the same as saying:
// x = function() {
// alert('inner function called');
// }
x(); // now the inner function is called
See this fiddle: http://jsfiddle.net/bBqPY/
Functions in JavaScript can return functions (that can return functions (that can return functions ...)). If you have a function that returns another function then it means that when you call the outer function what you get is the inner function but it is not called yet. You have to call the value that you got as a function to actually run the body of the inner function. So:
x = f();
means - run a function f and store what it returns (which may be a string, a number, an object, an array, or a function) in x. But this:
x = f()();
means - run a function f, expect it to return a function and run that returned function as well (the second parentheses) and store in x what the returned function returned.
The function f here is a higher order function because it returns another function. Functions can also take another functions as arguments. One of the most powerful ideas of functional programming languages in general and JavaScript in particular is that functions are just normal values like arrays or numbers that can be returned and passed around.
You have to first grasp the idea of higher order functions to understand closures and the event system in JavaScript.
2016 Update
Note that currently this:
function outer() {
return function() {
alert('inner function called');
}
}
can be written as:
let outer = () => () => alert('inner function called');
using the ES6 arrow function syntax.
The amazing part about closures is that an inner function (in this case, childFunction) can refer to variables outside of its scope (in this case, variable). parentFunction doesn't return the result of childFunction, but an actual reference to the function!
This means that when you do the following...
var child = parentFunction();
...now, child has a reference to childFunction, and childFunction still has access to any variables it had when the function was created, even if they no longer exist.
In order to have parentFunction call childFunction, you'd need to change your code as follows:
From...
return childFunction;
To:
return childFunction();
Douglas Crockford (Pioneer of JSON, among other things) has a whole article devoted to closures, and scoping in javascript, and it would be well worth it to check out his other articles on javascript.
The point that is being demonstrated is that the function that was returned and assigned to child is still referencing the variable that was declared inside parentFunction instead of the one that was declared outside where child() is being invoked.
The only way to create a variable scope in javascript is in a function body. Normally the variable inside the parentFunction would have been discarded after the function returned.
But because you declared a function inside parentFunction that referenced variable in that scope and passed it out of parentFunction, the variable in the parentFunction is retained via the reference made in the new function.
This protects variable from outside manipulation except by functions that closed around it inside parentFunction.

Categories