首页 > 代码库 > python作用域和JavaScript作用域

python作用域和JavaScript作用域

JavaScript

  一、JavaScript中无块级作用域

  • 一个大括号一个作用域,就属于块级作用域,在Java和c#才存在块级作用域

function Main(){    if(1==1){        var name = ‘seven‘;    }    console.log(name);}// 输出: seven

 

  二、JavaScript采用函数作用域

  • 在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量

function Main(){    var innerValue = http://www.mamicode.com/‘seven‘;>

 

  三、JavaScript的作用域链

  • 由于JavaScript中的每个函数作为一个作用域,如果出现函数嵌套函数,就会出现作用域链

xo = ‘alex‘;  function Func(){    var xo = "seven";    function inner(){        var xo = ‘alvin‘;        console.log(xo);    }    inner();}Func();
  •  如果出现作用域链后,那么寻找变量时会出现顺序,是根据作用域链从内到外的优先级寻找,逐步往上找,没找到就抛出异常

技术分享

 

  四、JavaScript的作用域链执行前已创建

xo = ‘alex‘; function Func(){    var xo = "seven";    function inner(){         console.log(xo);    }    return inner;} var ret = Func();ret();// 输出结果: seven

 上述代码,在函数被调用之前作用域链已经存在:

上述代码,在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。

 

xo = ‘alex‘; function Func(){    var xo = "eirc";    function inner(){         console.log(xo);    }    xo = ‘seven‘;    return inner;} var ret = Func();ret();// 输出结果: seven

 

 

上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。

 

xo = ‘alex‘;<br>function Bar(){    console.log(xo);} function Func(){    var xo = "seven";         return Bar;} var ret = Func();ret();// 输出结果: alex

 

 

上述代码,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> Bar函数作用域
  • 全局作用域 -> Func函数作用域

当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。

 

  五、声明提前

  • 在JavaScript中如果不创建变量,直接去使用,则报错

console.log(xxoo);// 报错:Uncaught ReferenceError: xxoo is not defined
  •  JavaScript中如果创建变量而不赋值,则默认赋值为undefined

var xxoo;console.log(xxoo);// 输出:undefined

 而如果这么写

function Foo(){    console.log(xo);    var xo = ‘seven‘;} Foo();// 输出:undefined

 上述代码,不报错而是输出undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值,所以,相当于上述实例中,函数在‘预编译’时,已经执行了var xo;所以上述代码中输出的是undefined

 

python

  • python能够改变变量作用域代码关键词:def、 class、 lambda

  • if语句,try异常捕获,for/while循环语句都不涉及变量作用域的更改,也就是他们的代码块中的变量,在外部也是可以访问的

def main():    if True:        name = ‘seven‘    print(name)main()#sevendef Main():    inner = ‘seven‘Main()print(inner)#NameError: name ‘inner‘ is not defined
  •  python内部也是采用作用域链的形式,优先级是根据作用域从内到外找

name = ‘alex‘def func():    name = ‘seven‘    def inner():        name = ‘eric‘        print(name)    inner()func()
#eric

 

name = ‘alex‘def func():    name = ‘seven‘    def inner():        print(name)    return innerret = func()ret()#seven
  •  函数被调用之前作用域链已经创建好

name = ‘alex‘def bar():    print(name)def func():    name = ‘seven‘    return barret = func()ret()#alex

当内部作用域想修改外部作用域的变量时

  •  修改的变量是在全局作用域上的,就要使用global声明

  • 修改的变量在嵌套作用域上,就要使用nonlocal声明

#全局作用域count = 10def outer():    global count    print(count)    count = 100    print(count)outer()# 10# 100#嵌套作用域def outer():    count = 10    def inner():        nonlocal count        count = 20        print(count)    inner()    print(count)outer()# 20# 20
  •  变量查找顺序:作用域局部>外层作用域>当前模块中的全局作用域>python内置作用域

python作用域和JavaScript作用域