以下Python程序A输出
所有程序A的输出都是1。Python和Javascript与C++之间在程序B中的差异源于它们不同的作用域规则:在C++中,变量的作用域从其声明开始,而在Python和Javascript中,它从变量声明所在块的开头开始。因此,在函数f中打印变量x的C++解析为全局变量x的值1,因为它是执行此时上下文中唯一的变量。在Python和Javascript中,在函数f中打印变量x会解析为空,并引发未绑定本地变量x错误,因为此时执行上下文中已经存在本地变量x,并且因此掩盖了全局变量x,但还没有绑定到值2。Python和Javascript的这种反直觉行为也称为变量提升,因为它将变量声明(但不是定义)“提升”到块的开头。
编程语言中变量提升的优点和缺点是什么?
1
,正如预期一样,而以下Python程序B会出现未绑定本地变量x
错误,这与直觉相悖。
- 程序A:
def f(): print(x)
x = 1
f()
- 程序 B:
def f(): print(x); x = 2
x = 1
f()
Javascript有完全相同的行为。
- 程序A:
function f() { console.log(x); }
let x = 1;
f();
- 程序B:
function f() { console.log(x); let x = 2; }
let x = 1;
f();
然而,C++在这两种情况下输出预期的结果1
。
- 程序A:
#include <iostream>
int x;
void f() { std::cout << x; }
int main() { x = 1; f(); return 0; }
- 程序 B:
#include <iostream>
int x;
void f() { std::cout << x; int x = 2; }
int main() { x = 1; f(); return 0; }
所有程序A的输出都是1。Python和Javascript与C++之间在程序B中的差异源于它们不同的作用域规则:在C++中,变量的作用域从其声明开始,而在Python和Javascript中,它从变量声明所在块的开头开始。因此,在函数f中打印变量x的C++解析为全局变量x的值1,因为它是执行此时上下文中唯一的变量。在Python和Javascript中,在函数f中打印变量x会解析为空,并引发未绑定本地变量x错误,因为此时执行上下文中已经存在本地变量x,并且因此掩盖了全局变量x,但还没有绑定到值2。Python和Javascript的这种反直觉行为也称为变量提升,因为它将变量声明(但不是定义)“提升”到块的开头。
编程语言中变量提升的优点和缺点是什么?
var
和函数作用域),您可以运行“愚蠢”的代码而不会中断执行。缺点是难以调试的逻辑错误。 - Teemuvar
不像let
那样会中断执行,因为它将值undefined
分配给本地变量x
而不是什么都不分配,但是本地变量x
的作用域仍然与let
一样遮蔽全局变量x
。 - Géry Ogamlet
(和const
)的上下文中,使用了一个术语暂时性死区
。 - Teemu