为什么。那么()链接到Promise.resolve()允许常量声明被重新分配?为什么。那么()链接

2019-05-12 13:48发布

鉴于与声明的变量const不能被重新分配或删除看

  • 有没有在JavaScript中的常量?

  • JavaScript的const关键字

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

为什么有可能重新分配的值与声明的变量const传递给函数内.then()链接到Promise.resolve()其中const变量传递,但它是不可能的重新分配const与传递给函数的变量.then()链接到Promise在那里构造const变量传递给resolve()的参数Promise构造resolver功能?

 "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在最新的浏览器实现,我们目前拥有的最接近?

Answer 1:

你是不是分配给const变量。 你是不是分配给你给了相同名称的功能参数。 这个函数的参数是可变的非常拷贝,所以你被允许分配给它。

我会尽量收集我所有的意见,以更全面地解释的答案。

在代码在这里:

"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变量会抛出异常。

然后,当你这样做:

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

这声明了一个.then()处理函数,它有一个参数,该参数的名称是state 。 当.then()处理程序被调用,无论是作为一个参数来传递的.then()处理程序复制到名为新参数变量state 。 功能参数不是const 。 它们可以被分配到。

因为你现在已经创建了两个独立的变量具有相同的名称,一个是在较高的范围,当你在里面.then()处理器,命名的函数参数state “覆盖”或“隐藏”相同的另一个变量名称。 当您尝试访问state里面.then()处理程序,唯一的变量,您可以访问使用这个名称的时候就是函数的参数。 该函数的参数是借助于被传递到其他状态变量的副本.then()处理程序作为一个参数。 所有函数的参数是副本。 JavaScript有没有真正的引用变量类型。

此外函数参数不是const ,所以你可以分配给他们。

所以,当你state = "456"; 这里面.then()处理程序,你只是分配给函数的参数。 因为你已经创建了一个命名冲突,实际上是没有办法进入更高的作用域const state变量。 该JS解释认为是最接近的范围,你试图访问它的定义。


我想你的困惑将被清除,如果你只是停止创建冲突的变量名。 如果你不喜欢这样(命名参数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变量,解释器将对象。


作为最好的,我知道,JavaScript有没有办法防止覆盖更高的范围变量具有相同名称的本地范围内的新声明的变量。 这只是不是一种语言功能。 当解释解决了一个变量名,它搜索从地方到全球,从而局部定义范围内的层次结构中找到(和使用)第一。 较高的作用域的定义是指范围内“被覆盖的”或“隐藏”。 这就是他们是如何设计的变量名称解析的语言进行工作。

有这许多好处太有人突然宣布不使用更高的范围变量或者甚至不知道的永远不会意外地打破你的下范围的声明。 当你自己声明冲突,你真的想使用范围的命名越高,这只是一个编码错误。 你不申报名称冲突,如果你打算使用相同名称的高等范围变量。



Answer 2:

这里常量state变量没有发生变化。 您正在改变其传递给决心函数的参数值。 你可以通过简单地做验证这一点console.log(state)所有代码和输出后,将是123



文章来源: Why does .then() chained to Promise.resolve() allow const declaration to be reassigned?