python 和 js 变量作用域问题的不理解

发布于 2022-09-07 19:56:45 字数 806 浏览 22 评论 0

本人目前刚学习python, 遇到了关于变量作用域的一些问题, 如下:

下面这个就不是非常明白

a = 3
def f():
    a += 4
    print(a)
f() # UnboundLocalError: local variable 'a' referenced before assignment

然后如果稍微改一下:

a = 3
def f():
    b = a + 4
    print(a)
f() # 3

这里新声明了一个变量b, 对a进行了引用, 然后就可以访问到a了, 不是明白为什么

另外如果将代码 1 换成js, 结果又不同

var a = 3
const f = () => {
    a += 4
    console.log(a)
}
a() // 7
f() // 7

js中不仅仅能够访问到全局变量, 甚至可以对全局变量进行修改, 所以在js里面作用域机制和python又有什么区别?

另外, 本人所了解到jspython都是静态作用域, 原理应该相同, 但是上面显示的结果却很不一样, 麻烦能有前辈清楚的解答一下, 本人才学疏浅, 见谅!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我来给你解释一下吧,
对于举例中的python和js中var定义的变量,他们作用域规则相似

  1. 变量作用域在定义它的函数内(整个python或js文件可以看做一个大函数)
  2. 根据第1点:函数内出现与全局中定义的同名变量,在函数内,它会覆盖全局的。

不同点

  1. js函数内定义变量要明确在变量名前写上var(我们先不讨论let和const),否则就是直接调用全局的
  2. python中定义变量直接写变量名
  3. pyhton函数中如果想给全局变量赋值,需要在赋值之前写上 global 变量名

基于以上前提知识,请看注释中的解释

Python的代码

a = 3        # 全局的a
def f():
    a += 4   # a=a+4, 相当于先重新定义一个新变量a'(函数体f内的a), 
             # 然后执行a'+4时报错:”没有赋值就使用“
    print(a) # 没执行到这步就,已经在上面报错了。
f() #调用时被报错
a = 3        # 全局的a
def f():
    global a # 加上这句后,下面再给赋值,就是针对全局变量了。
    a += 4   # 全局的a被加4,变为7了
    print(a) # 
f() #7
a = 3
def f():
    b = a + 4# 此处的a是全局的a
    print(a) # 打印的是全局的a,没上面那句b的赋值此处也是全局的a
f() # 3

Javascript的代码

var a = 3
const f = () => {
    a += 4             // 没有用var,此处引用的是全局a
    console.log(a)
}
a   // 3  此处因为还没执行f函数,a还没有被改变 
f() // 7  你的问题描述中写的4,正确是7
a   // 7  执行过f(), 全局的a已经被改变
半边脸i 2022-09-14 19:56:45

python
a += 4 其实就是a = a + 4

此时 相当于在函数内部声明了变量 a, 所以是调用不到外部的a的。

而在 js 中 a 并不是声明的新变量,所以结果会不同。

js 中声明变量是需要 var 之类的关键字的,python 不需要

如果想要python 中的 a 的指向全局需要明确指定

a = 3
def f():
    global a // 明确指定是全局变量
    a += 4
    print(a)
f()

python 的代码转换为 js 代码其实是这样的:

var a = 3;
const f = () => {
    var a;
    a += 4;
    console.log(a) // NaN 因为js的容错机制,所以并没有报错。
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文