Understanding the concept of callbacks and scopes

While experimenting with the concept of callbacks, I encountered a scenario where I wanted to confirm that my understanding of the situation was correct.

function greet(callback) { // 'greet' function utilizes a callback
  var greeting = "hi";     // 'greeting' variable is defined within the scope
  callback()               // 'callback' function is called 
}

greet(
function() {
  console.log(greeting)
}); 

//Console does not display anything

It's quite interesting. One would expect the callback() to reference its immediate scope and access the 'greeting' variable. However, when I move the definition of the 'greeting' variable to the global execution context, then it works as expected.

var greeting = 'hi'        // 'greeting' variable is defined globally

function greet(callback) { // 'greet' function takes a callback    
  callback()               // 'callback' function is invoked 
}

greet(
function() {
  console.log(greeting)
}); 

//Console logs: 'hi'

Could this be because the callback() function that logs the variable is actually declared in the global context? Therefore, rather than searching inside greet(), it directly looks in the global environment due to its declaration.

I just wanted to ensure that I correctly comprehend what's happening here, instead of facing some unexpected scope or block-related issue.

Answer №1

It is true that the function has access to the scope in which it is defined.

An example of this concept would be:

var message = 'hello';

function sayHello(callback) {
    callback();
}

function logMessage() {
    console.log(message);
}

sayHello(logMessage);

Here, logMessage can access message because they are in the same or higher scope level.

However, if we were to move message inside the sayHello function:

function sayHello(callback) {
    var message = 'hello';
    callback();
}

function logMessage() {
    console.log(message);
}

sayHello(logMessage);

In this case, logMessage cannot access message as it is now in a different scope altogether.

The scope that logMessage can reach is where it is defined, not where it is called from. So, the scope is determined at the time of definition rather than invocation.

Answer №2

Lexical scope in JavaScript refers to how the language handles scope, as opposed to dynamic scope. Simply put, lexical scope determines the context based on where variables and functions are defined, while dynamic scope is determined by where they are called.

If your first example were to follow dynamic scope, it would behave differently than you expected.

To delve deeper into this topic, check out the "Lexical scope vs. dynamic scope" section.

Learn more about scope in computer science here

Answer №3

In Javascript, the concept of Static Scoping is used.

To summarize; Variables are resolved based on their position in the source code.

The variable greeting is only accessible within the closure of the greet function. Any code outside this closure cannot access the greeting variable.

function greet(callback) { // 'greet' function with a callback
  var greeting = "hi";     // defining 'greeting' variable in this scope
  callback()               // invoking the 'callback' function 
}

greet(function() {
  console.log(greeting)
}); 

In this case, the greeting variable is defined in a scope that can be reached by nested closures of both the greet function and the anonymous function passed to the console.log call.

var greeting = 'hi'        // setting 'greeting' variable globally

function greet(callback) { // 'greet' function with a callback    
  callback()               // invoking the 'callback' function 
}

greet(function() {
  console.log(greeting)
});

NOTE: The this keyword follows different rules.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Embedding an Iframe in Angular 2 directly from the database

Looking for assistance with iframes in Angular 2. Initially, embedding an iframe directly into a component's template functions correctly. <iframe src='http://plnkr.co/edit/zZ0BgJHvQl5CfrZZ5kzg?p=preview | safeUrl' allowtransp ...

Mastering the use of gl Scissor is essential for effectively implementing popups in your

I am attempting to implement a pop-up view on top of the current webGL view. My strategy is as follows: Whenever I need to display a popup, I create a scissorRect and begin rendering the popup scene onto it. I was hoping that the content of the previous s ...

What is causing these dynamic carousels to malfunction in Chrome?

After using Agile Carousel successfully for a while, I am now experiencing issues with it not working properly in Safari and Chrome, although it functions fine on Firefox and Safari for iPad. On this specific page, the carousel stops at the second image, ...

Is it possible to create a functionality in Google Sheets where a cell, when modified, automatically displays the date of the edit next to it? This could be achieved using a Google

Here is the current code snippet I have: function onEdit(e) { var range = e.range; var val = range.getValue(); var row = range.getRow(); var col = range.getColumn(); var shift = 1; var ss = SpreadsheetApp.getActiveSheet().getRange(row, (col+ ...

Do you need to finish the Subject when implementing the takeUntil approach to unsubscribing from Observables?

In order to prevent memory leaks in my Angular application, I make sure to unsubscribe from Observables using the following established pattern: unsubscribe = new Subject(); ngOnInit() { this.myService.getStuff() .pipe(takeUntil(this.unsubscr ...

Listen for a click event on an Unordered List using addEventListener

Struggling to transform a for loop that iterates through an unordered list of hyperlinks and adds an 'onclick' function to each into one using an event listener instead. Unfortunately, I have not been able to create a functional solution. Below ...

How to create a blinking effect for buttons in an Angular app with ng-if or ng-show

I've come across the same issue in two separate angular projects I've been involved with, but have not been able to find any discussion on this particular problem. This leads me to believe that there may be something I am overlooking. Let's ...

Tips for choosing elements in JavaScript using querySelector even after they've been included in the code using innerHTML

Within the scenario below, a parent element is present in the HTML code and the span element with a class of 'child' is nested within the parent element using the createChild function. Subsequently, the content of the child element is modified el ...

"Enhance your web development skills by mastering jQuery alongside the

It's curious that jQuery doesn't support the use of the "+" sign. You can see how it functions with "1" and "3", but not with "2+". Just hover your mouse over each div to experience it. <div id="div-2+"></div> JSFiddle $('a. ...

Update the text using JavaScript to modify the price range dropdown when the user clicks away

Dropdown functionality is working when selecting a price, but updating the price in the text box manually does not trigger an update. How can you implement an onblur change event for manual entry of prices? JSFiddle function nFormatter(num, digits) { ...

Click on an element using jQuery to apply a specific class to all other similar

I am looking to dynamically add a class to a DIV after clicking on an A element with the same class. Here is an example: <ul> <li><a href="#1" class="test1">1</a></li> <li><a href="#2" class="test2">2</a>< ...

Unable to assign the value 'hello' to an undefined property in TypeScript

I'm attempting to define a class in TypeScript, but I keep encountering the error shown below. Here is the execution log where the error occurs: [LOG]: "adding" [LOG]: undefined [ERR]: Cannot set property 'hello' of undefined class Cust ...

Error encountered: A syntax error occurred due to an unexpected token ":" found in the file path D:practise odejs odejs-demoviewsindex.html

Attempting to switch the engine view from .ejs to .html resulted in an error. After searching online, I was unable to find a solution for the following problems: Express 500 SyntaxError: Unexpected token : in D:\practise\nodejs\nodejs-demo& ...

Guide to appending the chosen item from a search bar to a fresh array using vue3 js

Does anyone know how to resolve the issue I'm facing with adding selected items from a dropdown list to a new array and displaying them on the page? Currently, I have added an onblur event to the input field to hide the dropdown when clicked outside, ...

When using NodeJS, having multiple 'if' statements may result in conflicting headers being returned,

Introduction to Promises. Encountering challenges in NodeJS due to the utilization of multiple if-statements and return-statements. Considering leveraging Promise as a potential solution. This snippet showcases an example: const express = require(' ...

Tips for resolving the trigger problem with onChange in the PinInput Component of chakra-ui

The PinInput Component's onChange event is not functioning properly with the value in Chakra-UI. This issue causes the focus to automatically shift to the next input even when the value hasn't changed. For instance, when attempting to set the st ...

Personalize your message in a JavaScript alert using Bootstrap notifications

On numerous websites, a new visitor landing on the page is greeted with an alert notification that pops up in either the bottom right or left corner. The code below functions perfectly fine, except for my unsuccessful attempts to change the message text w ...

What is the process for sending a request and obtaining a response from a REST API using JavaScript?

I have a private server set up on my computer with a built-in REST API. The base URL for the API is: . I am now looking to develop a client application for this server using the API. To authenticate on the server, the API endpoint is baseurl/login with the ...

What are the ways in which the "npm install <module>" command can be utilized in the creation of web pages for browsers?

When incorporating a resource into a web page, I have the option to either link to the file (locally, hosted by the web server, or on a CDN) <link rel="stylesheet" href="https://somecdn.com/mycssresource.min.css"> <script src="alocalscript.js"> ...

What is the reason for the inability to access a global variable type variable outside of the $.each function when used within the $

While analyzing a code snippet, I came across an issue with a variable causing an error. function call(data) { $.each(data, function(index, value) { var ddlId = 'ddlCat' + data[index].docId; var html = '<tr id="supp_doc_row_&ap ...