Invocation

Invocation occurs, in its most simple form, by explicitly calling a function. We do this by attaching calling parentheses ((...)) to a value we know to be a function. This value on the left side of (...) can be a direct reference to a variable or property that holds a function or any expression that evaluates to a function:

someFunction();
(function(){})();
someObject.someMethod();
[function(){}][0]();

To construct instances, as we've explored, you can use the new operator. This is also a type of invocation although, in the case of zero arguments, it doesn't technically require calling parentheses:

function MyConstructor() {}

// Both equivalent:
new MyConstructor();
new MyConstructor;

The exact syntax of evaluation before the calling parentheses (on the left side of (...)) is not important as long as it evaluates to a function. If it does not, then you will receive TypeError:

1();     // ! TypeError: 1 is not a function
[](); // ! TypeError: [] is not a function
'wat'(); // ! TypeError: "wat" is not a function

When a function is called, JavaScript will create a new Lexical Environment (a scope) in which that function will be evaluated, and the function will become the current execution context, shifting control from the current area of code to the function's code. This should not be too unintuitive. It makes sense that, in the code, foo();, baz();, and foo() will be given control and will run to completion before baz() is then given control.

A function will return control to you in the following ways:

  • By returning (implicitly or via an explicit return statement)
  • By throwing (implicitly due to SyntaxErrorTypeError, and so on or via an explicit throw statement)
  • By yielding (in the case of a generator)

Invocation can also occur indirectly, via JavaScript's internal mechanisms. For example, in the case of coercion, as explored in the last chapter, methods such as valueOf, toString, or Symbol.toPrimitive may be called in various scenarios. Additionally, JavaScript enables you to define setters and getters so that your custom functionality is activated whenever a given property is accessed or assigned to:

const person = {
set name(name) {
console.log('You are trying to set the name to', name);
}
};

person.name = 'Leo';
// Logs: "You are trying to set the name to Leo"

By assigning to the name property here, we are effectively invoking a function, which itself may then do all manner of things, potentially invoking other functions itself. You can imagine how the control flow of a given program can become potentially incomprehensible when there are many implicit means of invocation such as this. Such implicit mechanisms do have their advantages, but if too much of our problem domain's logic is embedded within such places, then it's less plainly visible to our fellow programmers and hence more likely to cause confusion.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.171.162