What is a "scoping function" in javascript? - 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.

Related

What are the arguments to this javascript factory assigned to?

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().

Difference between closures and IIFE's in javascript

According to the Closures concept it will store the variables of the outer lexical environment for future execution of its inner function. For example:
function makeYounger(age) {
function b() {
console.log("Original age is :" + age);
}
b();
return(function() {
return age / 2;
});
}
var displayAge = makeYounger(20);
console.log(displayAge());
In the above scenario, age is preserved by the Javascript engine to execute the inner function present in the return method.
Here comes the IIFE:
(function(window) {
var greeting = "Hello";
var fNameSpace1 = {
name : "Appu",
callName : function() {
console.log(greeting + fNameSpace1.name);
}
};
window.doer = fNameSpace1;
}) (window);
fNameSpace1.callName(); //To execute the inner function
In the above scenario according to the closures concept the variables greeting and fNameSpace1.name will be stored for future execution of the callname() function. Instead we are making use of the window object. I am confused why we are going with window if we have closures?
IIFE is useful to avoid global variable pollution when multiple functions are accessing a global variable
Closure functions are helpful when working with a local variable.
Difference between closures and IIFE's in javascript
An IIFE is just one specific way to A) Create a closure over the context in which it's defined, and B) Create a context in which to create other closures.
My question is what is the exact use of window object in this scenario if the javascript engine already stores fNameSpace1 object.Why are we creating a reference using window?
So it can be used outside the IIFE, by referring to it via the doer global that window.doer = ... creates.
There are dozens of different ways to do this. One of them does it by assigning to window like that. Another does it by returning the value and using a var statement:
var doer = (function() {
// ...
return fNamespace1;
})();
but again, there are dozens of different formations. The author of that particular one just preferred to write to a property on window as the way to create the global.

Ways to break JavaScript Scope

JavaScript normally follows the function scope i.e. variables are accessible only within the function in which they are declared.
One of the ways to break this convention and make the variable accessible outside the function scope is to use the global window object
e.g.
window.myVar = 123;
My question is are there any other ways in JavaScript/jQuery to make the variable accessible outside the function scope?
Not with variable declarations, no. You can obviously declare a variable in an outer scope so that it's accessible to all descendant scopes:
var a; // Available globally
function example() {
a = "hello"; // References a in outer scope
}
If you're not in strict mode you can simply remove the var keyword. This is equivalent to your example:
// a has not been declared in an ancestor scope
function example() {
a = "hello"; // a is now a property of the global object
}
But this is very bad practice. It will throw a reference error if the function runs in strict mode:
function example() {
"use strict";
a = "hello"; // ReferenceError: a is not defined
}
As you wrote, variables are only visible inside the function in which they were defined (unless they are global).
What you can do is assign variables to the function object itself:
function foo() {
foo.myVar = 42;
}
console.log(foo.myVar); // outputs "undefined"
foo();
console.log(foo.myVar); // outputs "42"
But I would advise against it. You should really have a very good reason to do something like this.
You can define them as part of a global object, then add variables later
// Define your global object
var myObj = {};
// Add property (variable) to it
myObj.myVar = 'Hello world';
// Add method to it
myObj.myFunctions = function() {
// Do cool stuff
};
See the link below:
Variable declaration
Also, you can declare it without the var keyword. However, this may not be a good practice as it pollutes the global namespace. (Make sure strict mode is not on).
Edit:
I didn't see the other comments before posting. #JamesAllardice answer is also good.

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.

A simple question about Javascript functions, differences in invocation/definition

Can someone please explain the difference between the following function definitions?
var alertMessage = function alertMessage(message) {
alert(message);
}
var alertMessage = function(message) {
alert(message);
}
What are the implications of each? Thanks!
Both are function expressions, basically the difference is that the first is named, and the second one is anonymous.
For example:
var test = function test(message) {
alert(message);
};
var test1 = function(message) {
alert(message);
};
test.name; // "test"
test1.name // "" or "anonymous"
Note: The name property of function objects exist on some implementations, but it's non-standard.
Also, the name of function expressions it's useful for debugging, as you can inspect the call stack to see where you are.
This identifier is only accessible from inside the FunctionBody itself:
(function foo(){
typeof foo; // "function"
})();
typeof foo; // "undefined"
However there is a bug on the JScript implementation (in all versions of IE), which this name is leaked to its enclosing scope.
Both definitions are function expressions, as opposed to function declarations, or functions created by the Function constructor. They both assign a function to the variable alertMessage. The difference is that the first function is named, while the second is anonymous.
Named functions are usually used in function declarations, eg
function alertMessage(message) { ... }
In that case, the function declaration creates a variable in the current scope called alertMessage that references that function. Function declarations are hoisted to the top of the current scope, so you can call declared functions before they're defined in you js file.
A named function used in a function expression (such as the original question) does not create this variable, or get hoisted to the top of the execution scope, so by convention most function expressions are anonymous. The only benefits to naming a function expression are that the name variable is bound within the function (although as CMS mentions, this is implementation dependent) and the function name is output from the function's toString method. This can be useful during debugging (rather than having Firebug output (?) for a huge list of anonymous function calls).
Much more detail at MDC

Categories