【问题标题】:Why is a 'undefined' in this code?为什么此代码中有“未定义”?
【发布时间】:2018-12-14 01:58:57
【问题描述】:

var a = 10;

function Obj() {
  console.log(a);
  let a = 10;
}

Obj()

在调用函数时 a 的 Obj 值被打印为未定义

【问题讨论】:

标签: javascript ecmascript-6 variable-declaration hoisting


【解决方案1】:

你的错误是:

1:你不需要函数将消息记录到控制台,你可以直接调用它,如果将它注销。 示例:

  Let a = 10 
  console.log(a)

结果将是 10

2:当你初始化一个全局变量同时也初始化一个函数时,同时调用它们会抛出错误或多次渲染。 示例:

  Let a = 10;
  function Obj() {
    console.log(a)
    let a = 10;
  }

Obj() // this and the global will intend to run once, which will cause error.

最佳做法是将您的函数作为回调调用,以便在触发事件时记录 示例:

btn.addEventListener("click", obj)

当这个按钮被点击时,它会记录 10

【讨论】:

    【解决方案2】:

    var a = 10;
    
    function Obj() {
      console.log(a);
      let a = 10;
    }
    
    Obj()

    Function 也是一个对象,对于它的属性,第一个 a:undefined 执行未定义的读取(阅读关于在 javascript 中提升的内容!)。

    【讨论】:

      【解决方案3】:

      在您的情况下,代码在第一个控制台上中断。由于a 的范围在函数内,并且您在打印之前没有定义它。

      我已经做了一些例子来向你展示不同的初始化场景。

      const derp = 10
      
      const blerg = (derp) => {
       console.log('Checking case1: ', derp)
       //Reason: Here derp is the prop passed to the function and passed undefined to it.
      }
      
      const blerg2 = (derp) => {
       console.log('Checking case2: ', derp)
       //Reason: Here derp is the prop passed to the function
      }
      
      const blerg3 = () => {
       console.log('Checking case3: ', derp)
       // Throws Error
       //Reason: Here derp scope is within the function and not defined so far.
      let derp = 20
      console.log('Checking case4: ', derp)
      // This line won't print because already code broke on the above console.
      }
      
      blerg()
      blerg2(derp) // Passing the derp initialised on line 1
      blerg3() // Passing nothing to the function

      【讨论】:

        【解决方案4】:

        当你调用Obj() 函数时。 JavaScript 引擎会像下面这样读取 -

        function Obj() { 
            let a;  //variable hoisting
        
            console.log(a); 
        
            a = 10;     
        }
        

        所以没有变量初始化变量的值将是未定义的。

        【讨论】:

        • 不,它不是,let 不是这样工作的。 var 就是这样 运行上面的代码,你会在控制台看到错误。
        【解决方案5】:

        首先您需要了解使用let 声明的变量具有块作用域。而且您不能在同一范围内再次声明相同的变量,这会出错。
        因此,在您的情况下,您在函数末尾声明 a。所以还没有声明。

        而不是使用var 来声明变量,它不会抛出这样的错误,但会返回undefined

        为了更好地理解let 的概念,您可以通过以下链接。

        1. let variable
        2. var variable

        【讨论】:

          【解决方案6】:

          a 不是未定义的。该函数返回未定义,因为您没有指定它应该返回什么。它实际上会返回一个错误,但如果它要运行,您会看到未定义。

          代码一起为您提供:

          Uncaught ReferenceError: a is not defined

          由于作用域,在本地,函数作用域中,a 稍后用 let 定义,它覆盖了函数之前的定义。

          你可以尝试两件事:

          • 如果您尝试console.log(window.a),您将获得正确的值(外部 a,定义在函数范围之外的值)。

          • 如果您将let a = 10; 移动到功能块的开头,您将获得该值。

          【讨论】:

            【解决方案7】:

            在声明之前访问 let 和 const 值可能会因为临时死区而导致 ReferenceError

            【讨论】:

              【解决方案8】:

              Javascript 使用范围链来建立给定函数的范围。通常有一个全局范围,并且定义的每个函数都有自己的嵌套范围。在另一个函数中定义的任何函数都具有链接到外部函数的局部范围。定义范围的始终是源中的位置。

              作用域链中的元素基本上是一个带有指向其父作用域的指针的 Map。

              当解析一个变量时,javascript 从最里面的范围开始向外搜索。

              如果你这样写,你的例子就会运行:

              console.log(this.a);
              

              【讨论】:

                【解决方案9】:

                没有任何返回值的函数,默认返回undefined

                您的Obj函数将运行并输出控制台日志,但它会返回未定义。意思是“函数的返回值没有定义”。

                如果您是 JS 新手,请勾选此项 :) https://www.w3schools.com/js/js_mistakes.asp

                【讨论】:

                • 但该函数不会在其当前状态下返回任何内容
                • 确切的返回值是未定义的。我不明白你想要达到的目标。你只是在运行一个函数。甚至没有将返回值分配给一个值。
                • 我不是 OP.... 该函数不会返回,因为它会引发错误。这就是我的推断。
                • 这个答案不准确; OP 的代码不运行并引发引用错误。
                • 代码甚至没有尝试打印函数的返回值,所以它返回的内容完全不相关。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-10-04
                • 2012-05-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多