标签:
额……写博客什么的好像很难的样子……脑子一下子空了~~~
算了不矫情了,就当做捋一捋~~没准写着写着就High了。
js作用域可以简单理解两句话。由上到下,由内到外
(一)预解析
我们来看一段代码
alert(a); var a = 2;
运行结果是undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。即a = undefined
function a() { console.log(1); } alert(a);
运行结果:
在预解析阶段JS解析器会找关键字var,function,变量等。
这时存入的是一段代码块,即 a = function a() {
console.log(1);
}
在全局作用域中遵循一个简单规则由上而下,在看一段代码,猜一猜结果吧
alert(a); function a (){ alert(4); } var a = 1; alert(a); function a (){ alert(3); } alert(a);
结论:JS 的预解析遇到重名的只留一个, 变量和函数重名了,就只留下函数
(二)执行环境及作用域的概念
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之相关的变量对象。环境中定义的所有变量和函数都保存在变量对象中。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
每个函数都有自己的执行环境。
fn1执行完毕后函数的执行环境被销毁,在函数内声明的变量a也随之销毁。
原谅我一直停留在小学时期的画图水平吧~~
当试行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
到这里插一句话,像我上图的例子里这样执行的函数都是同步滴~~同步任务在执行栈中~~推荐阅读阮一峰大神的JavaScript 运行机制详解:再谈Event Loop
www.ruanyifeng.com/blog/2014/10/event-loop.html
(三)作用域链
当代码在一个环境中执行时,会创建一个作用域链。作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。作用域的前端始终都是当前执行的代码所在环境的变量对象。作用域链中的下一个变量对象来自包含(外部)环境。作用域链的最后一个对象始终是全局执行环境的变量对象。即作用域链遵循由内到外的简单规则
现在把我那张小学生水平的图稍作改动
fn1的作用域链,开始是fn1的变量对象,然后是来自包含环境的变量对象,在这里是全局变量对象。
fn2执行时,执行a(),遇到arg1会顺着作用域链寻找arg1,会先从函数a变量对象中寻找arg1,没有就去作用域链上的下一个变量对象fn2的变量对象上寻找,没有就继续作用域链上下一个变量对象全局变量对象中寻找,这里找到了arg1 = true.
总结一下,内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境中的任何变量或函数。
(四)没有块级作用域
在JavaScript中没有块级作用域。
嘿嘿==,关于这个问题只要记住这句话就够了~~额……当然不会就说这么一句话,不来点干货我都不好意思==
在其他类c语言中,由花括号{}封闭的代码块都有自己的作用域,但是js没有块级作用域!!!
如果存在块级作用域应该报错,因为a是一个局部变量,在全局是找不到a的。
但是运行结果a = 9,所以不存在块级作用域。
(五)this
(六)call
标签:
原文地址:http://www.cnblogs.com/kikiwu/p/4474074.html