zoukankan      html  css  js  c++  java
  • python作用域和JavaScript作用域

    JavaScript

      一、JavaScript中无块级作用域

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

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

      二、JavaScript采用函数作用域

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

    function Main(){
        var innerValue = 'seven';
    }
     
    Main();
     
    console.log(innerValue);
     
    // 报错:Uncaught ReferenceError: innerValue is not defined
    

      三、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()
    #seven
    
    def 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 inner
    
    ret = func()
    ret()
    #seven
    
    •  函数被调用之前作用域链已经创建好

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

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

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

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

    #全局作用域
    count = 10
    
    def 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内置作用域

  • 相关阅读:
    提交按钮变灰
    解析spring启动加载dubbo过程
    shiro的SecurityUtis
    spring集成shiro登陆流程(下)
    spring集成shiro登陆流程(上)
    shiro的DelegatingFilterProxy怎么找到ShiroFilterFactoryBean
    sql多表关联
    android常用控件
    android控件之EditText
    浅议iOS网络数据解析
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/5925700.html
Copyright © 2011-2022 走看看