Different JavaScript function format - javascript

I've been wondering what is the difference between:
function getBasicRow() {}
getBasicRow : function() {}
I've seen the 2nd function used by vtiger CRM and hifive (http://www.htmlhifive.com/)

The second one assigns the function to a property on some object literal, so the scope of the function is determined by the property.
The first one creates a named function without assigning it to a variable. The function will be hoisted to the closest function scope.

An elobrative explanation that I found here and would like to share it.
The different ways in which a function can be defined in javascript are:
function A(){}; // function declaration
var B = function(){}; // function expression
var C = (function(){}); // function expression with grouping operators
var D = function foo(){}; // named function expression
var E = (function(){ // immediately-invoked function expression (IIFE) that returns a function
return function(){}
})();
var F = new Function(); // Function constructor
var G = new function(){}; // special case: object constructor
What exactly is hoisting?
The interesting thing about these is that they are “hoisted” to the top of their scope, which means this code:
A();
function A(){
console.log('foo');
};
Gets executed as this code:
function A(){
console.log('foo');
};
A();
Which practically means that, yes, you can call the functions before they’re written in your code. It won’t matter, because the entire function gets hoisted to the top of its containing scope.
Variable declaration hoisting
Variable declarations are hoisted to the top of their scope, somewhat similarly to function hoisting except the contents of the variable are not hoisted as well. This happens with all variables, and it means it’s now happening with our functions, now that we’re assigning them to variables.
This code:
var A = function(){};
var B = function(){};
var C = function(){};
Will be executed as this:
var A, B, C; // variable declarations are hoisted
A = function(){};
B = function(){};
C = function(){};
Therefore the order of setting and calling this type of function is important:
// this works
var B = function(){};
B();
// this doesn't work
B2(); // TypeError (B2 is undefined)
var B2 = function(){};
The second example gives us an error because only the variable B2’s declaration is hoisted, but not its definition, thus the “undefined” error.
Courtesy: DavidBCalhoun

Related

JavaScript Hoisting - Hoisted code after Memory Creation phase

I was reading Kyle Simpson book: https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch4.md#functions-first.
But I don't fully understand this line "Notice that var foo was the duplicate (and thus ignored) declaration, even though it came before the function foo()... declaration, because function declarations are hoisted before normal variables."
Let's say this is the code:
console.log(foo); // The output is: foo() { return 2; }
function foo() {
return 1;
}
function foo() {
return 2;
}
var foo = 3;
I want to visualize what would be the output in JS Engine after Memory Creation phase. Will it be like this?
function foo() {
return 2;
}
console.log(foo);
If yes, why var foo = 3; was ignored? There is no duplicate for var in the snippet. If no, can anyone please help me visualize what would be the output in JS Engine after Memory creation phase?
Thanks
I think the text refers to
// scope creation
var foo; // the name was declared. Thrice.
foo = undefined; // from the var
foo = function foo() { return 1 }; // from the first declaration
foo = function foo() { return 1 }; // from the second iteration
// execution
console.log(foo);
;
;
foo = 3;
where foo is initialised with undefined due to the var foo declaration, but then gets overwritten by the initialisation value from the function foo declaration which takes precedence - regardless of the order in which the declarations appeared in the code, function declarations overrule var declarations.
Function declarations
Declare a variable with the same name as the function (this is hoisted)
Assign the function to that variable (this is hoisted)
var statements with associated assignments
Declare a variable with that name (this is hoisted)
Assign the value to that variable (this is not hoisted)
var foo = 3 is not ignored.
The variable declaration (var foo) is ignored because the earlier function declarations already declared that variable. (i.e. because it duplicates the declaration of foo).
foo = 3 is not ignored and does assign 3 to foo … it just does so after your console.log statement runs because it isn't hosited.

Way to understand this code. How is it working?

I was exploring scopes in javascript and came to know this problem. I don't understand how this problem is working.
function checkType() {
return foo;
foo = 10;
function foo() {};
var foo = 11;
};
console.log(typeof checkType())
My question is this how does javascript compiler decide to return function not variable. Any reference or explanation are welcome.
This is how the compiler will compile the above code..
function checkType() {
var foo = function() {}; /* function will be hoisted to the top,
and will be assigned to the variable as
the name is the same for the two.. */
return foo;
// Code will never reach here as you are returning before this
foo = 10;
foo = 11;
};
console.log(typeof checkType());
Functions which are defined using function() syntax will be hoisted, in this case, the nested function will be hoisted insde the checkType() and hence, the checkType() returns the function instead of the integer.
Note: Because the function was defined using function(){} syntax, it
was hoisted to the parent function scope, else, if the function was
defined using var foo = function() {} then the hoisting would not
have worked in the same way, your function would've returned undefined instead.
More reference on Scoping & Hoisting
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/
First all the function declarations are hoisted in a scope. So first of all the code moves the variable foo to the top of the scope and initialize its value to function.
The second declaration of variable is not hoisted because the function declaration is already hoisted. So the code is same as
function checkType() {
var foo = function(){}
return foo;
foo = 10;
foo = 11;
};
When we run a code there are two phase of it first is creation phase in this phase the syntax parser will read the code and hoist the function and variables, and second phase is execution phase in which the values are assigned to hoisted variables,
A point to note here is function are stored in memory during creation phase as it is where as the variables are hoisted but values
are not initialized ( which will be assigned during execution phase )
Compiler will treat your code like this after hoisting
function checkType() {
var foo = function() {}; //hoisted function
return foo;
foo = 10;
foo = 11;
};
console.log(typeof checkType(), '\nRturned value from function --->', checkType())
If you define your function as variable than it will be hoisted only but will not be initialized with value, you can see the below example
function checkType() {
return foo;
foo = 10;
var foo = function foo() {};
var foo = 11;
};
console.log(typeof checkType(), '\nRturned value from function --->', checkType())

TDZ in undeclared variables of function parameters [duplicate]

This question already has an answer here:
Scope of Default function parameters in javascript
(1 answer)
Closed 4 years ago.
When I try to run the foo function defined in this snippet I get a ReferenceError since b is not defined.
var b = 3;
function foo( a = 42, b = a + b + 5 ) {
// ..
}
foo()
This looks like a TDZ error because b has been defined in the outer scope but it's not yet usable in the function signature as a right-hand-side value.
This is what I think the compiler should do:
var b;
function foo(..) { .. }
// hoist all functions and variables declarations to the top
// then perform assignments operations
b = 3;
foo();
//create a new execution environment for `foo`
// add `foo` on top of the callstack
// look for variable a, can't find one, hence automatically create a
`var a` in the local execution environment and assign to it the
value `42`
// look for a `var b` in the global execution context, find one, use
the value in it (`3`) as a right-hand-side value.
This shouldn't raise a ReferenceError. Looks like this is not what happens here.
Can someone explain in what actually does the compiler do and how it processes this code?
On every function call, the engine evaluates some prologue code, which contains formal parameters, declared as let vars and initialized with their actual values or default expressions, if provided:
var b = 3;
function foo( ) {
let a = <actual param for a> OR 42;
let b = <actual param for b> OR a + b + 5;
// ..
}
Since b in a function is lexical (let), it's not possible to access its value before initialization. Hence the ReferenceError.
Note that this is a call-time error, so the following compiles fine:
var b = 1
function foo(b=b) {
console.log(b)
}
The error happens when you actually call the function:
var b = 1
function foo(b=b) {
console.log(b)
}
foo()
and only when the engine actually evaluates the faulty default expression:
var b = 1
function foo(b=b) {
console.log(b)
}
foo(7)
ECMA standard reference: FunctionDeclarationInstantiation, p.21:
For each String paramName in parameterNames, do
...Perform ! envRec.CreateMutableBinding(paramName, false).
The function arguments somewhat works like 'let'.
We cannot access variable created using 'let' before they are declared .i.e variables created using 'let' are not hoisted.
This happens because if the we are declaring the variable in local scope , it cannot access the global scope variable(Unless 'this' is used )
Your code can be fixed by this -
var b = 3;
function foo( a = 42, b = a + this.b + 5 ) {
// default binding. In this case this.b = global var
}
foo()
you can also see this error if you do this.
let variable = variable;

Defining a variable inside IIFE block

Can someone explain what is the difference between following two IIFE blocks:
a) (f1 = function(){console.log('IIFE Block1')})()
b) (var f1 = function(){console.log('IIFE Block2')})()
I understand that "b)" upon execution will throw error.
What is the use of defining the variable "f1" and what are its properties.
a only works outside of strict mode. f1 is being implicitly defined as a global variable and set to the value of your IIFE. If you try this in strict mode, an error will be thrown because f1 hasn't been explicitly declared with var, let, const, or as a function argument:
function quirks() {
(f1 = function() { return 'f1 IIFE'; })();
return f1;
}
console.log(quirks());
function strict() {
"use strict";
(f2 = function() { return 'f2 IIFE'; })();
return f2;
}
console.log(strict());
The first one doesn't use a declaration keyword, so f1 will become global (which defeats the purpose of the IIFE). But, that is legal syntax for an expression - the function can be invoked and the result (if any) can be assigned to f1. Note that this won't work with use strict in effect.
(f1 = function(){console.log('IIFE Block1')})()
// f1 is Global and can be accessed from anywhere
console.log(f1);
The second one fails because it's invalid IIFE syntax - it is a declaration and assignment statement, which is not an expression that can be evaluated.
(var f1 = function(){console.log('IIFE Block2')})()
In addition to all the great answers, you'll realize that most of this is syntactic allowance. You can apply the same methodology of the first one, which is operating on the window object, to any other defined object:
(f1 = function(){console.log('IIFE Block1')})()
console.log(f1);
// managed object
var local = {};
(local.f2 = function(){console.log('IIFE Block2')})()
console.log(local.f2);
// or any predefined variable
var f3;
(f3 = function(){console.log('IIFE Block3')})()
console.log(f3);
// just not in the parens
// (var f4 = function(){console.log('IIFE Block4')})()
// console.log(f4);

javascript object gets overridden in IE

Geeks,
I have the following codes:
Snippet A:
var x = (function(){ this.id="Dog"; return this; }());
var y = (function(){ this.id="Cat"; return this; }());
alert(x.id); //outputs Cat
alert(y.id); //outputs Cat
Snippet B:
var x = (new function(){ this.id="Dog"; });
var y = (new function(){ this.id="Cat"; });
alert(x.id); //ouputs Dog
alert(y.id); //outputs Cat
Why is x replaced by y in Snippet A and not on B?
The difference between the two is that Snippet B is using a constructor function by prefixing the call with the new keyword, while snippet A is not. This is the short answer.
The long answer is that although snippet A introduces a new scope on each anonymous function invocation, since it is not being used in a constructor context it's this variable simply points to the global window object. So snippet A is equivalent to this:
var x = (function(){ window.id="Dog"; return window; }());
var y = (function(){ window.id="Cat"; return window; }());
Thus, each invocation just clobbers the same [global] variable.
Since snippet B is using the new keyword, you define and immediately call a constructor function. JavaScript proceeds to initialize the this variable inside the constructor function to point to a new instance of the [just defined] anonymous function.
You may have seen the new function(){} idiom some time ago being touted as the best way to define and immediately execute a block of code. Well, it comes with the overhead of JavaScript object instantiation (as you've found), and is not generally used as widely anymore.
In the snippet A, on x and y, the this keyword refers to the global object, you are creating setting the value to the same global variable (window.id).
In the snippet B, you are using the new operator, and the functions are executed as constructor functions, the this keyword refers to a newly created object.
To avoid that behavior in your snippet A, you can create a new object instance and use it instead of this:
var x = (function(){
var instance = {};
instance.id = "Dog";
return instance;
}());
var y = (function(){
var instance = {};
instance.id = "Cat";
return instance;
}());
alert(x.id); //outputs Dog
alert(y.id); //outputs Cat
When you call global functions, since they are members of the global object:
globalFunction();
Is equivalent to:
window.globalFunction();
And the context inside that function will be the global object itself (window).

Categories