In depth analysis of functions mechanism in JS
Function are objects in JS and hence they have a prototype. The advantage of function being objects is that they can be easily passed as arguments to other functions or objects. There are 3 main methods in Function's prototype:
.call()
and.apply()
: they do significantly the same thing, ie executing a function while letting you specify a different 'this' than the natural one (that you pass in the first argument). The difference between the two is that arguments in addition tothis
are passed individually in.call()
and as an array in.apply()
.
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
// we add Product constructor to Food, which is represented as the 'this' argument in .call()
Product.call(this, name, price);
this.category = 'food';
}
let food = new Food('cheese', 5).name); // -> 'cheese'
.bind()
: this function creates a new function that is a copy of the target function but that, when called, has itsthis
keyword set to the provided value, plus a set of arguments that will take precedence over the ones from the target function:
var module = {
x: 42,
getX: function() {
return this.x;
}
}
var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined -> this is because this.x is not defined in the global scope.
var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
A Function Declaration defines a named function variable without requiring variable assignment. Function Declarations occur as standalone constructs and cannot be nested within non-function blocks. It’s helpful to think of them as siblings of Variable Declarations. Just as Variable Declarations must start with “var”, Function Declarations must begin with “function”.
A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment ). Functions defined via Functions Expressions can be named or anonymous. Function Expressions must not start with “function”
//anonymous function expression
var a = function() {
return 3;
}
//named function expression
var a = function bar() {
return 3;
}
//self invoking function expression
(function sayHello() {
alert("hello!");
})();
- for function declarations: Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter.
- for function expressions: variable declarations get hoisted but their Assignment Expressions don’t. So if a function expression has been assigned to a variable, the variable is hoisted and set to undefined and will then take a value when it is reached in the code.
An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.
Possible syntax
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }
// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }
// Parenthesize the body of function to return an object literal expression:
params => ({foo: bar})
// Rest parameters and default parameters are supported
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements }
// Destructuring within the parameter list is also supported
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6