Variable and Function Hoisting in JavaScript
The trickier aspects of JavaScript for new JavaScript developers are the facts that variables and functions are "hoisted." Rather than being available after the declaration, they might actually be available beforehand. Let's take
a look at variable hoisting first.
// ReferenceError: noSuchVariable is not defined
console.log (noSuchVariable);
// Outputs: undefined
console.log(declaredLater);
var declaredLater = "Now it's defined!";
// Outputs: "Now it's defined!"
console.log(declaredLater);
It turns the JavaScript treats variables will be declare later on in a function differently than variables that are not declared at all. The JavaScript interpreter "looks ahead" find the all variables and declare "hoists" to the top of the
function. Which mean that the example above is equivalent to this:
var declaredLater;
// Outputs: undefined
console.log(declaredLater);
declaredLater = "Now it's defined!";
// Outputs: "Now it's defined!"
console.log(declaredLater);
One case where this is particularly likely to bite new JavaScript developers is when reusing variable names between an inner and outer scope. For example:
var name = "Baggins";
(function () {
// Outputs: "Original name was undefined"
console.log("Original name was " + name);
var name = "Underhill";
// Outputs: "New name is Underhill"
console.log("New name is " + name);
})();
The developer probably expected name to retain its value from the outer scope until the point that name was declared in the inner scope. But due to hoisting, name is undefined instead.
This behavior of JavaScript linters and style guides often recommend put all the variable declarations at the top of the function so that you won't be caught by surprise.
That the covers variable hoisting, but what about function hoisting? Both "hoisting," the behavior is actually quite different. The variables, a function declaration doesn't just hoist the function's name. It also hoists the actual
// Outputs: "Yes!"
isItHoisted();
function isItHoisted() {
console.log("Yes!");}
The JavaScript interpreter allows us to use the function before the point it was declare in the source code. This is useful because it allows us to express our high-level logic at the beginning of our source code rather than the end.
travelToMountDoom();
destroyTheRing();
function travelToMountDoom() { /* Traveling */ }
function destroyTheRing() { /* Destruction */ }
The function definition hoisting only occurs for function declarations, not function expressions. For example:
// Outputs: "Definition hoisted!"
definitionHoisted();
// TypeError: undefined is not a function
definitionNotHoisted();
function definitionHoisted() {
console.log("Definition hoisted!");}
var definitionNotHoisted = function () {
console.log("Definition not hoisted!");};
The hoisting has two types of interactions.
// ReferenceError: funcName is not defined
funcName();
// TypeError: undefined is not a function
varName();
var varName = function funcName() {
console.log("Definition not hoisted!");};
0 comments:
Post a Comment