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内置作用域

最新文章

  1. BestCoder Round #43
  2. php 加密解密方法
  3. PYTHON多进程编码结束之进程池POOL
  4. linux获取目录下文件
  5. 读懂Java中的Socket编程
  6. 我学cocos2d-x (两) 采用Delegate(信托)
  7. delete操作字符串会报错吗?
  8. OpenResty和Resis一些基本的性能配置
  9. Linux学习笔记--vi
  10. __x__(31)0908第五天__导航条的练习 &lt;ul&gt; 版本
  11. sql获取当前月份的前一月,当前天的前一天,当前年的前一年
  12. java中的多线程入门
  13. MySQL查询优化注意下面的四个细节
  14. AutoFac记录
  15. 同一个电脑安装两个jdk版本
  16. 浅谈FFT、NTT和MTT
  17. Redis——总结
  18. samba创建权限(复制)
  19. 007PHP文件处理—— 判断文件与操作文件fopen fread fclose is_executable is_readable is_writeable
  20. Go语言面组合式向对象编程基础总结

热门文章

  1. iOS Core ML与Vision初识
  2. HDU - 1358 - Period (KMP)
  3. SVN checkout 功能不可用 右键只看到提交和更新,没有显示checkout
  4. atitit.RandomAccessFile&#160;rws&#160;rwd&#160;的区别于联系
  5. Django学习之raw()方法查询数据
  6. int 与 string::length()
  7. codeforces #364b Cells Not Under Attack
  8. C语言指针解说
  9. Python的实例方法,类方法,静态方法之间的区别及调用关系
  10. PHP 高精度计算