【问题标题】:Why inside a function you can use a variable that's declared later为什么在函数内部可以使用稍后声明的变量
【发布时间】:2020-08-31 18:37:45
【问题描述】:

我正在写一个Dialog组件,突然想到这个想法。

export const alert = (content: string) => {
  const buttons = [<button onClick={()=>closeModal()}>ok</button>] // quite ok 
  // const buttons = [<button onClick={closeModal}>ok</button>] // raise an error
  const closeModal = modal(content, buttons)
}

错误是:在声明之前使用了块范围变量“closeModal”。我习惯于在 React 的函数中包装一些表达式,从来没有想过。

情况可以简化为:

const caller = () => {
  func() // ok
}
const funcAgain = func // error
func() // error
const func = () => {}

这种行为叫什么?跟闭包有关系吗?还是变量提升?

【问题讨论】:

    标签: javascript reactjs typescript function closures


    【解决方案1】:

    这与变量声明和范围管理以及执行阶段的基础有关。 这里阻塞作用域变量(let,const)的变量声明实际上是提升的,但没有初始化。 Js引擎简单地拒绝对未初始化变量标识符的任何操作。

    还有一个著名的术语称为时间死区(TDZ)。在这种情况下,func 位于其 TDZ 中。

    希望这会有所帮助。

    【讨论】:

    • 所以在callercaller 中找到TDZ 中的func。而且js引擎不关心func是否初始化,只要声明func
    • 不,这不准确。重要的是,任何变量声明都需要在使用之前进行初始化。无论是函数声明、变量声明还是块范围声明。您应该阅读有关吊装的更多信息,这将为您提供更好的图片。
    • 知道了。 caller 在全局范围内找到尚未初始化的已提升 func。但是函数方法可能稍后会调用,所以没关系。如果我将 caller 转换为 IIFE,我尝试过,它会引发错误,因为 func 未初始化。非常感谢
    【解决方案2】:

    好问题。 onClick 在第一个示例上有效,因为它返回一个新的 Function 对象。函数体在被调用之前不会被评估。

    ()=>closeModal()
    

    我认为您指的是“吊装”。要提升一个函数,您需要声明如下

    const caller = () => {
      func() // ok
    }
    func() 
    function func () {}
    

    【讨论】:

    • 通常在 Javascript 中传入需要稍后计算的参数的方式是通过函数而不是直接传入该表达式
    猜你喜欢
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2015-02-10
    • 2012-04-25
    • 1970-01-01
    • 2022-11-30
    相关资源
    最近更新 更多