额……写博客什么的好像很难的样子……脑子一下子空了~~~
算了不矫情了,就当做捋一捋~~没准写着写着就High了。
js作用域可以简单理解两句话。由上到下,由内到外
(一)预解析
我们来看一段代码
alert(a);var a = 2;
运行结果是undefined。在使用var声明变量但未对其加以初始化时,变量声明会提升至顶部,这个变量的值就是undefined。即a = undefined。
function a() {console.log(1);}alert(a);
运行结果:
在预解析阶段JS解析器会找关键字var,function,变量等。
这时存入的是一段代码块,即%20a%20=%20function%20a()%20{%20console.log(1);}
这个过程叫做函数声明提升。解析器会率先读取函数声明并添加到执行环境中。
补充一个函数表达式
1%20console.log(a());2%20var%20a%20=%20function%20()%20{3%20%20%20%20%20return%203;4%20};
运行结果:%20a%20is%20not%20a%20function
函数表达式和函数声明在解析器向执行环境中加载数据时并不一样处理。函数表达式必须等到解析器执行到它所在的代码行才会真的被解释执行。并不会提升。
在执行到函数所在的语句之前,变量a中不会保存有对函数的引用。
在全局作用域中遵循一个简单规则由上而下,在看一段代码,猜一猜结果吧
alert(a);function%20a%20(){%20alert(4);%20}var%20a%20=%201;alert(a);function%20a%20(){%20alert(3);%20}alert(a);
结论:JS%20的预解析遇到重名的只留一个,%20变量和函数重名了,就只留下函数
(二)执行环境及作用域的概念
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之相关的变量对象。环境中定义的所有变量和函数都保存在变量对象中。对象变量只在函数执行过程中存在。但是全局变量对象始终存在。
某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
每个函数都有自己的执行环境。
fn1执行完毕后函数的执行环境被销毁,在函数内声明的变量a也随之销毁。
原谅我一直停留在小学时期的画图水平吧~~
当试行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
到这里插一句话,像我上图的例子里这样执行的函数都是同步滴~~同步任务在执行栈中~~推荐阅读阮一峰大神的Javascript 运行机制详解:再谈Event Loop
www.ruanyifeng.com/blog/2014/10/event-loop.html
(三)作用域链
新闻热点
疑难解答