这段代码演示了JavaScript中一个常见的行为,称为变量提升。在JavaScript中,变量声明会被提升到其作用域的顶部,但赋值操作仍然保持在原位置。
当调用example()函数时,它首先尝试打印a的值。在函数内部,有一个var a = 20;语句,它在函数作用域内创建了一个新的局部变量a。然而,由于提升,var a;的声明被提升到函数的顶部,实际上使函数等同于:
在trickyExample()函数中,if块前后都有一个console.log(a)语句。在块内部,有一个var a = 10;声明。由于变量提升,var a;声明被提升到函数作用域的顶部,使其在整个函数中都可以访问。
然而,在JavaScript中,在块内用var声明的变量不是块作用域的;它们是函数作用域的。这意味着在if块内声明的变量a在整个trickyExample()函数中都可以访问,甚至在if块之前也可以。
当调用trickyExample()时,第一个console.log(a)语句将输出undefined,因为a被提升但还没有被赋值。第二个console.log(a)语句将输出10,因为a已经在if块内被赋值为10。
这个问题探讨了在JavaScript中块内用var和let声明的变量之间的差异。
在trickyFunction()中,有一个if块包含var a = 5;和let b = 10;声明。用var声明的变量是函数作用域的,并被提升到函数的顶部,而用let声明的变量是块作用域的,不会被提升。
当调用trickyFunction()时,var a被提升到函数的顶部,在整个函数中都可以访问。然而,let b是块作用域的,只在if块内可以访问。
第一个console.log(a)语句将输出5,因为var a由于提升而在整个trickyFunction()函数中都可以访问。
第二个console.log(b)语句将导致ReferenceError,因为let b被块作用域限制在if块内,在块外无法访问。
在给定代码中,变量variable被声明并赋值为10。在立即调用函数表达式(IIFE)内部,同一个变量被用var重新声明并赋值为20。由于提升,第一个console.log(variable)打印undefined(变量被声明但还没有被赋值),第二个console.log(variable)打印20。这演示了JavaScript中提升和变量重新声明的影响。
代码以全局变量a设置为1开始。在函数b()内部,声明了一个局部函数a,它暂时遮蔽了全局a。b()将10赋给局部a,但这不会影响全局a。console.log(a)语句打印未改变的全局a,结果是输出1。
在评论区中,有读者提到了另一个有趣的JavaScript陷阱:
小心浮点数精度问题! 这个例子展示了JavaScript中浮点数运算可能出现的精度问题。