python作用域和JavaScript作用域

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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内置作用域

以上是关于python作用域和JavaScript作用域的主要内容,如果未能解决你的问题,请参考以下文章

下面JavaScript代码如何理解?块级作用域如何理?

JavaScript中的作用域和闭包

JavaScript中作用域和作用域链解析

JavaScript作用域和作用域链

JavaScript作用域和作用域链

JavaScript高级JavaScript的运行原理:V8引擎,JS代码执行原理,作用域和作用域链面试题