Python 和 JavaScript 变量赋值区别
·
Python
- 有无作用域链?
- 有 根据LEGB 规则 (Local -> Enclosing -> Global -> Built-in)
- 只读外层变量
- 直接读取,不需要任何关键字
- 修改外层变量
- 必须显式声明 nonlocal(否则当成局部变量报错)
- 为什么 Python 需要 nonlocal?(Python 的规则)
def outer_fn(): a = 100 def inner_fn(): nonlocal a a += 1 print(f"当前a的值是:{a}") return inner_fn # 在 Python 中,单纯的“读取”和“赋值(修改)”遵循完全不同的规则。 # 读取(Look up): 遵循 LEGB 规则(Local -> Enclosing -> Global -> Built-in)。这就是 Python 的作用域链。如果不做修改,inner_fn 内部可以直接打印 a,它会沿着作用域链去外层找。 # 赋值(Assignment): Python 有一个硬性规定——只要你在函数内部对一个变量进行了赋值(比如 a = ... 或 a += 1),Python 在编译阶段就会认定这个变量是当前函数的“局部变量(Local)”。 - nonlocal 作用:
nonlocal a 的存在,就像是给编译器递了一张假条,告诉它:“别在当前函数里创建局部变量 a 了,顺着作用域链往外找,用外层那个 a!”
- 设计哲学
- 显式优于隐式(防止你不小心污染外层变量)
JavaScript
- 有无作用域链
- 有(Scope Chain)
- 只读外层变量
- 直接读取,不需要任何关键字
- 修改外层变量
- 自动沿着作用域链向上查找并修改
- 为什么 JavaScript 不需要关键字?
function outer_fn() { let a = 100 function inner_fn() { a += 1 } return inner_fn } # 为什么 JavaScript 不需要关键字?(JS 的规则) # 1. JavaScript 的作用域链(Scope Chain)在处理赋值时更加“顺其自然”: # 2. 当执行 a += 1 时,JS 引擎首先在 inner_fn 的局部作用域找 a。 # 3. 没找到?JS 不会像 Python 那样直接报错,而是动态地顺着作用域链向外层(outer_fn)查找。 # 4. 在外层找到了 let a = 100,于是直接在原地把它修改成了 101。
- 设计哲学
- 灵活、方便(但也容易误修改外层变量)
更多推荐



所有评论(0)