为什么 .then() 链接到 Promise.resolve() 允许重新分配 const 声明? [英] Why does .then() chained to Promise.resolve() allow const declaration to be reassigned?

查看:21
本文介绍了为什么 .then() 链接到 Promise.resolve() 允许重新分配 const 声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设用 const 声明的变量不能重新赋值或删除,请参见

Given that a variable declared with const cannot be reassigned or deleted see

JavaScript const 关键字

是否可以删除一个使用 const 声明的变量??

为什么可以在传递给 .then() 并链接到 Promise.resolve() 的函数中将值重新分配给使用 const 声明的变量 其中 const 变量被传递,但不可能重新分配 const 变量,并将函数传递给 .then() 链接到 Promise 构造函数,其中 const 变量被传递给 Promise 构造函数 resolverresolve() 参数代码>功能?

why is it possible to reassign a value to a variable declared with const within a function passed to .then() chained to Promise.resolve() where const variable is passed, but it is not possible to reassign the const variable with function passed to .then() chained to Promise constructor where const variable is passed to resolve() parameter of Promise constructor resolver function?

"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)); 
}

编辑、更新

为了阐明查询的基础和动机,该问题试图确定何时可以使用与 const 声明相同的标识符,以及何时不可能使用该过程.从本质上讲,尝试创建一个在任何范围内抛出错误的标识符,其中尝试为标识符分配不同的值 - 无论是函数范围,块范围还是代码中的任何地方 - superconst" indetifier,或者当前可能最接近该描述的,取决于引擎.MapWeakMapclass 是我们目前在最新浏览器实现中最接近的吗?

To clarify the basis and motivation for the inquiry, the Question is an attempt to determine when an identifier can be used which is the same as a const declaration, and when that procedure is not possible. In essence, trying to create an identifier which throws an error in any scope where an attempt is made to assign the identifier a different value - whether function scope, block scope or anywhere in the code - a "superconst" indetifier, or the closest to that description currently possible, depending on the engine. Are Map or WeakMap or class the closest we currently have at newest browser implementations?

推荐答案

您没有分配给 const 变量.相反,您将分配给您赋予相同名称的函数参数.该函数参数是变量的非常量副本,因此您可以对其进行赋值.

You are not assigning to the const variable. You are instead assigning to the function parameter that you gave the same name. That function parameter is a non-const copy of the variable so you are allowed to assign to it.

我会尽量将我所有的评论收集到一个更完整解释的答案中.

I will try to collect all my comments into a more fully explained answer.

这里的代码:

"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));

首先,定义 const state = "123" 变量.任何试图改变那个确切的 state 变量的内容都会抛出异常.

First, you define your const state = "123" variable. Any attempt to change the contents of that exact state variable will throw an exception.

然后,当你这样做时:

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

它声明了一个 .then() 处理函数,它接受一个参数,该参数的名称是 state.当 .then() 处理程序被调用时,作为那个参数传递给 .then() 处理程序的任何内容都被复制到这个名为 state 的新参数变量中.函数参数不是 const.他们可以分配给.

That declares a .then() handler function that takes one argument and the name of that argument is state. When the .then() handler is called, whatever is passed as that one argument to the .then() handler is copied into this new argument variable named state. Function arguments are not const. They can be assigned to.

因为您现在已经创建了两个具有相同名称的独立变量并且一个在更高的范围内,所以当您在 .then() 处理程序中时,该函数参数名为 state 覆盖"或隐藏"同名的另一个变量.当您尝试访问 .then() 处理程序中的 state 时,使用该名称时您可以访问的唯一变量是函数参数.由于作为参数传递给 .then() 处理程序,该函数参数是另一个状态变量的副本.所有函数参数都是副本.Javascript 没有真正的引用变量类型.

Because you've now created TWO separate variables with the same name and one is at a higher scope, when you are inside the .then() handler, that function argument named state "overrides" or "hides" the other variable of the same name. When you attempt to access state inside the .then() handler, the ONLY variable you can access when using that name is the function parameter. That function parameter is a copy of the other state variable by virtue of being passed to the .then() handler as an argument. All function arguments are copies. Javascript has no true reference variable types.

此外,函数参数不是 const,因此您可以分配给它们.

Furthermore function arguments are not const so you can assign to them.

因此,当您在 .then() 处理程序中 state = "456"; 时,您只是分配给函数参数.因为您已经创建了命名冲突,所以实际上无法访问更高范围的 const state 变量.JS 解释器会找到范围最接近您尝试访问它的位置的定义.

So, when you state = "456"; inside that .then() handler, you are just assigning to the function argument. Because you've created a naming conflict, there is actually no way to access the higher scoped const state variable. The JS interpreter finds the definition that is closest in scope to where you are attempting to access it.

我认为如果您停止创建有冲突的变量名,您的困惑就会迎刃而解.如果你这样做(命名参数localState):

I think your confusion will be cleared up if you just stop creating a conflicting variable name. If you do it like this (name the parameter 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));

然后,当您尝试分配给 state 时,您将看到异常,因为您尚未创建具有相同名称的冲突局部变量,因此您尝试分配 state = 456 确实会尝试分配给 const 变量并且解释器会反对.

Then, you will see an exception when you attempt to assign to state because you have not created a conflicting local variable with that same name so your attempt to assign state = 456 will indeed be attempting to assign to a const variable and the interpreter will object.

据我所知,Javascript 无法防止在局部作用域中使用新声明的同名变量覆盖更高作用域的变量.那不是语言功能.当解释器解析变量名称时,它会从局部到全局搜索范围层次结构,因此首先找到(并使用)局部定义.更高范围的定义在该范围内被覆盖"或隐藏".这就是他们设计变量名称解析以在该语言中工作的方式.

As best I know, Javascript has no way to prevent overriding a higher scoped variable with a newly declared variable of the same name in the local scope. That just isn't a language feature. When the interpreter resolves a variable name, it searches the scope hierarchy from local to global so local definitions are found (and used) first. Higher scoped definitions are "overriden" or "hidden" within that scope. That's just how they designed variable name resolution to work in the language.

这样做也有很多好处,因为有人突然声明了一个您没有使用或什至不知道的更高范围的变量,永远不会意外地破坏您的低范围声明.当您自己声明冲突并且您实际上想要使用更高范围的命名时,那只是一个编码错误.如果您打算使用同名的更高范围的变量,则必须不要声明冲突的名称.

There are many benefits to this too in that somebody suddenly declaring a higher scoped variable that you aren't using or aren't even aware of will never accidentally break your lower scoped declarations. When you yourself declaring a conflict and you actually want to use the higher scoped named, that's just a coding mistake. You have to not declare a conflicting name if you intend to use the higher scoped variable of the same name.

这篇关于为什么 .then() 链接到 Promise.resolve() 允许重新分配 const 声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆