How does the chaining of .then() to Promise.resolve() enable the reassignment of a const declaration?

Exploring the limitations of declaring a variable with const, which restricts reassignment and deletion. For more information, refer to:

  • Are there constants in JavaScript?

  • JavaScript const Keyword

  • Is it possible to delete a variable declared using const??

Questioning the ability to reassign a value to a variable initiated as const within a function passed to .then() attached to Promise.resolve(), while unable to do so when utilizing a function passed to .then() linked to the creation of a new Promise where the const variable is passed as parameter to the resolve() method.

"use strict"
const state = "123";
Promise.resolve(state)
.then(state => {
  console.log(state); // `"123"`
  state = 456; // reassign `const` variable `state` to `"456"`
  return state
})
.then(state => console.log(state)) // `"456"`
// not reached
.catch(err => console.error(err.message));

{
  "use strict";
  const state = "123";
  new Promise(resolve => {
    console.log(state); // `"123"`
    state = "456"; // reassign `const` variable `state` to `456`
    resolve(state);
  })
  .then(state => {
    console.log(state);
  })
  // `Error: Assignment to constant variable.`
  .catch(err => console.error(err.message)); 
}


Edit, Updated

This query delves into the possibility of creating an identifier similar to a const declaration that remains immutable across scopes. The focus is on determining if such an identifier, like a "superconst", can exist in various contexts without being reassigned. Are structures like Map, WeakMap, or class the closest alternatives currently available to achieve this at the latest browser implementations?

Answer №1

You have not assigned a new value to the const variable. Instead, you are assigning a value to the function parameter that shares the same name. Since the function parameter is a non-const copy of the variable, you are allowed to make an assignment to it.

I will consolidate all my comments into a more detailed answer.

In the following code snippet:

"use strict"
const state = "123";
Promise.resolve(state).then(state => {
  console.log(state); // `"123"`
  state = 456; // reassign `const` variable `state` to `"456"`
  return state
}).then(state => console.log(state)) // `"456"`
  // not reached
.catch(err => console.error(err.message));

Initially, you define a const state = "123" variable. Any attempt to change the content of this particular state variable will result in an exception.

Then, when you execute this:

Promise.resolve(state).then(state => {

This statement creates a .then() handler function with a single argument named state. When the .then() handler is invoked, whatever is passed as the argument to the handler is copied into this new local variable named state. Function arguments are mutable and can be reassigned.

By having two separate variables with the same name but at different scopes, the function parameter named state inside the .then() handler takes precedence over the higher scoped variable with the same name. Within the .then() handler, when you refer to state, you are actually accessing the function parameter which is a copy of the original variable passed as an argument to the .then() handler. Javascript does not have true reference variable types, everything is passed by value.

Moreover, function arguments are not constants, so you can assign new values to them.

Therefore, when you write state = "456"; within the .then() handler, you are simply updating the function parameter. Due to the naming conflict, you cannot access the outer const state variable from within the handler, as the interpreter resolves the closest scoped definition of the variable with the given name.


Your confusion might clear up if you avoid creating conflicting variable names. By renaming the parameter to something unique like localState:

"use strict"
const state = "123";
Promise.resolve(state).then(localState => {
  console.log(state); // `"123"`
  state = 456; // reassign `const` variable `state` to `"456"`
  return state
}).then(state => console.log(state)) // `"456"`
  // not reached
.catch(err => console.error(err.message));

In this case, trying to assign a new value to state will lead to an exception since no conflicting variable has been declared locally with the same name. Therefore, your attempt to assign state = 456 will be recognized as an attempt to modify a const variable, triggering an error.


To the best of my knowledge, JavaScript lacks a built-in mechanism to prevent shadowing external variables with similarly named local variables. When interpreting variable names, the language searches through nested scopes starting from the innermost scope towards the global scope - causing local definitions to take precedence over external ones. This behavior was designed intentionally for preserving code integrity and preventing unintended modifications affecting unrelated parts of the program. Declaring conflicts with higher scoped variables inadvertently means choosing the local definition over the external one, leading to potential issues if not managed carefully.

Answer №2

The variable state remains constant throughout the code. The value being modified is actually a parameter passed to the resolve function. To confirm this, you can add console.log(state) at the end of your script, and the output will be 123.

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

Modify the DOM at a later time once the images have loaded. This particular action is being executed within the context of an

main.ts myFunction(){ this.service.getData().subscribe( response => { this.handleData(response); }, error => console.log(error), () => console.log('request done') ...

Switch out a new js file every time the page is reloaded

I have a JS file with various objects (var), and I'm looking to dynamically load a different object each time the page is loaded. For instance, upon page load, a new object 'temp' should be created with data from one of the objects in the JS ...

Troubleshooting Node.js problem related to ES6 and chokidar

I have encountered an issue while working with the npm module chokidar. The problem arises when the value returned by watcher.getWatched() is null. Is there something in relation to ES6 and this operator that I might be overlooking? Here is my entry file. ...

Using JavaScript or JQuery, is there a way to retrieve the favicon icon, Apple-touch icon, and title of a webpage?

Is it possible to extract just the favicon icon and title from a webpage using only an IFrame? For example, for a site like www.stackoverflow.com, I want to retrieve only its title and favicon icon/Apple-touch-icon. Are there any plugins or parsers avail ...

Designed radio buttons failing to activate when focused using a keyboard

I'm facing an issue with radio input buttons that I've dynamically added to a div using jQuery. They function properly when clicked with a mouse, but do not get activated when using the keyboard tab-focus state. NOTE: To style the radio buttons ...

Is there a way to place a button in the top-right corner next to my Bootstrap 5 card?

Can someone help me figure out how to position a button on the top right corner next to my bootstrap card? Here's the code I have so far: <div className="row p-5 m-2"> {savedEpisodes?.map((saved) => { return ( ...

Convert incorrectly formatted XML content into an HTML bulleted list

Currently, I am tackling a project that involves parsing an XML tree with less-than-ideal formatting. The task at hand is to create a UL structure from this XML data, but the challenge lies in all nodes having the same name with varying attributes. To achi ...

The name 'withStyles' is nowhere to be found

import * as React from "react"; import Button from "@material-ui/core/Button"; import * as PropTypes from "prop-types"; import {WithStyles} from '@material-ui/core'; import "./App.css"; import PageTwo from "./components/PageTwo"; ...

Deactivate the form outside of normal business hours

I need to create a form for a delivery service that only operates from 9am to 9pm. If a user submits the form outside of these hours, I want to redirect them to a page displaying the company's operating hours instead of a thank you page. For instance ...

Retrieve the unique identifier of a div using JavaScript/jQuery

I am faced with a situation where I have two sets of divs structured as follows: First Div <div class="carousel"> <div class="item active" id="ZS125-48A">...</div> <div class="item" id="FFKG-34">...</div> <div cl ...

The method defined in the external script for React is not recognized

For my React project, I am trying to import BlotterJS. In order to do so, I have added the following script in my index.html file: <script crossorigin src="https://rawgit.com/bradley/Blotter/master/build/blotter.min.js"></script> Wit ...

Modifying the class of an HTML element using JavaScript

Is it possible to dynamically change the class of an HTML element based on a user's selection with a radio button? I am facing an issue where I receive the following error message: "Error: missing ) after argument list Source File: website Line: 1, C ...

Error in Angular2: "Promise" name not found despite successful installation of global dependencies

I'm currently developing an application using Angular 2 and Node.js. I've already installed all the necessary dependencies specified in package.json. Inside this file, there is a postinstall command that should install the required dependencies m ...

Determine which checkbox is currently selected in Vue and send corresponding data based on the checked status

A radio form that is conditionally disabled by another checkbox. One radio button can send either true or false and the other has an input that sends some data. How can I determine which radio button is checked and decide whether to send true/false or the ...

Setting initial values for an object in JavaScript

I am currently seeking a method to store predefined values in a separate file for populating my function: Here is my function in index.js: const Modes = (array) => { return { name: array.name, funcionarioIncrease: array.funcio ...

Content Security Policy error due to Ruby on Rails integration with Stripe JS and Elements

I am currently developing a Ruby on Rails application and I am looking to incorporate Stripe payments using the stripe gem. My plan is to utilize Elements, as outlined in this documentation provided by Stripe. To include Stripe js, I have added the follow ...

What is the best way to retrieve data from a REST API using Vuex store?

I am currently utilizing Vuex to manage the state of my application. In order to retrieve data from a rest API via an Ajax Get request and display a list of objects, I am dispatching an action to fetch this data from the server. However, I am unsure how t ...

How do I rearrange the order of a collection in Firestore using a reference that I already have?

Is there a method to maintain a reference of the same collection while altering the ordering using firestore? TLDR: I am looking to achieve similar functionality as demonstrated in: , but since my data is sourced from firestore, I am struggling to find th ...

Tips for testing components with React JS using jest and enzyme

Attempting to perform a unit test on the code snippet below: handleChange = (e) => { let localState = Object.assign({}, this.state) localState[e.target.name] = e.target.value this.setState(localState) this.props.addMetaInformation(localState) } } I&a ...

When the ESC key is pressed during a keyup event, the value of event.which is determined to be

On my ASP.Net master page, I've implemented this jQuery code: jQuery(document).keypress(function(event) { alert('keypress() called. e.which = ' + event.which); if (event.which == 27) { jQuery(this).trigger(&a ...