在前端学习中,作用域这个问题一直被广泛提起,什么是作用域,什么又是作用域链?在Javascript中,怎么去理解这些概念都是学好这门语言的关键,所以在学习前端开发的过程中,我需要也很有必要去学习和总结下javascript----作用域。

  作用域并不难,但是去很少有人能稍微深入的解释什么是作用域,知其然而不知其所以然显然是远远不够的,所以我们就深入浅出一下,

  本片博文旨在深度去分析作用域,如有总结不到位之处,请读者海涵并在评论区指出。

  谈到作用域就不得不谈到一个名词----执行环境。什么叫执行环境呢?

  执行环境是Javascript中最为重要的一个概念,它定义了变量或函数有权访问其他数据,决定了他们各自的行为。那么在每个执行环境中都有一个叫做“变量对象”的object,执行环境中的所有变量和函数都保存在这个对象中,这个object是无法被访问到了,它只能在后台被javascript解释器访问到。

  浏览器在解析Javascript代码的时候会为每个函数创建一个执行环境,并在该执行环境中生成一个变量对象来存储变量和其内部的函数。我们常常用到的window就是最外围的执行环境,也叫全局执行环境,每个执行环境的代码执行完成之后,该环境被销毁,其中的变量对象也将被销毁,而全局执行环境只会在浏览器或网页关闭的时候被销毁,其他的执行环境(或者内部的)则为局部执行环境(函数)

  每个函数都有自己的执行环境,那么当代码的执行流进入到一个函数时,会将该执行环境推入到一个环境栈中,在函数执行完成之后又将其弹出,把对这个执行环境的控制权交还给之前的执行环境,当代码在一个执行环境中执行的时候,会将该环境中的变量对象连入到作用域链中。作用域链的作用就是保证对执行环境中的有权访问的变量和函数有序的访问。说到这里,大家可能有些迷糊啦,那么就用点代码和图片来解释下吧。

//window scope
var name0 = 'scope0'
console.log(name0) //这里可以访问到name0
function scope1(){
var name1 = 'scope1'
     console.log(name0,name1) //这里可以访问到name0,name1
function scope2(){ var name2 = 'scope2'
         console.log(name0,name1,name2) //这里可以访问到name0,name1,name2 
function scope3(){ var name3 = 'scope3'
              console.log(name0,name1,name2,name3) //这里可以访问到name0,name1,name2,name3
}
}
}

  当JS解释器去执行这段代码的时候,会生成4个执行环境,分别是window,scope1,scope2,scope3。然后再执行JS代码的时候,会把每个执行环境推入到执行栈中,并生成变量对象给连接到作用域链中(从上到下),最后生成的作用域链就为:

window→scope1→scope2→scope3

对于每个执行环境中的变量对象来说,它的作用域链就是它本生加上它之前的变量对象(例如scope2的作用域链就是scope2和它之前的scope1和window)。我们先前说道,每个执行环境中的变量对象就是该执行环境能够访问到了变量和函数,个人理解为这个函数就是变量对象的作用域链上其他的变量对象,那么就很好理解了,我们分析下上面代码scope2的变量对象上有哪些东西,首先是参数数组(arguments,这里为[])还有name2变量,然后是scope1的变量对象和全局变量对象。

  说了这么多,提了那么多概念和名词,我们好像只是说到了作用域链,但是并没有说到作用域,这不是扯淡嘛!!!!好吧,我们现在就来谈谈作用域。

  

  还是先来扯下概念吧。是每个执行环境可以通过作用域链向上访问这个他的作用域链的其他执行环境,但是不能向下访问。这个就是作用域啦。。。

  还是拿scope2函数来说吧,他可以访问name2,name1,name0但是不能访问name3,这个就是作用域的限定,他只能访问到scope1和window的执行环境(还有它本身)。额,就这么一小段,我自己都醉了,但是个人觉得作用域就这点东西,关键的是在与对执行环境、变量对象和作用域链的理解。这些才是扎实的理解Javascript作用域的关键。

  

  其实说到这里我感觉已经差不多了,第一次写那么长的博文,文章水准还有待提高,这篇文章主要是我在看《javascript高级程序设计》的看到作用域这小节,感觉作者写了太好了,于是乎加上了一些个人的理解就写了这篇博客。非常希望有对WEB开发有深刻理解的大大们提出批评和见解。

  

老生常谈的Javascript作用域问题的更多相关文章

  1. JavaScript作用域

    JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...

  2. 关于Javascript作用域及作用域链的总结

    本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...

  3. JavaScript作用域链

    之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...

  4. [译] 你该知道的javascript作用域 (javascript scope)(转)

    javascript有一些对于初学者甚至是有经验的开发者都难以理解的概念. 这个部分是针对那些听到 : 作用域, 闭包, this, 命名空间, 函数作用域, 函数作用域, 全局作用域, 变量作用域( ...

  5. Python自动化 【第十六篇】:JavaScript作用域和Dom收尾

    本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...

  6. 深入理解javascript作用域系列第一篇——内部原理

    × 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...

  7. 深入理解javascript作用域系列第二篇——词法作用域和动态作用域

    × 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...

  8. 深入理解javascript作用域系列第四篇——块作用域

    × 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...

  9. 深入理解javascript作用域系列第三篇——声明提升(hoisting)

    × 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...

随机推荐

  1. python 下的数据结构与算法---5:递归(Recursion)

    定义:递归就是不断分割整体成部分直到可以轻易解决分割出来的部分. 递归表达式三定律: 1:递归表达式必须有个最小单元     (最小单元既是停止递归调用以及能够直接运算的) 2:递归表达式在运算过程中 ...

  2. jq不识别拼接的对象id的解决方案

    今天在做项目时,遇到了这么个问题. 先声明一下,我的id都是动态变换的.从1-10呢. <div id="a1"></div> <div id=&qu ...

  3. 2016/01/10 C++ Primer 小记 —— 命令行编译环境配置

    OK!第一篇博文!自贺一下! 今日看了此书的前几页.嗯,说得挺全,基础易懂. 之前学过c++,但没用过命令行编译. 本人用的VS里的编译器,文件名是cl.exe,在VC目录下. 虽然有了编译器,但并不 ...

  4. [转]XML中必须进行转义的字符

    转自:http://jaenson.iteye.com/blog/945469 编写XML代码经常遗漏的常识: XML实体中不允许出现"&","<" ...

  5. hdu 4277 USACO ORZ (暴力+set容器判重)

    USACO ORZ Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. mysql索引之唯一索引

    mysql 的唯一索引一般用于不重复的字段,一般会把表中的id设为唯一索引,创建唯一索引的目的不是为了提高查询速度,而是为了避免数据重复,注意:唯一索引可以有多个,但是列值必须唯一,创建唯一索引使用关 ...

  7. js分页算法

    function get_hs_page(cur_page, total_page) { var result = ""; for(var i = 1; i <= total ...

  8. Visual Studio发布项目到远程服务器的步骤

    第一步: 需要远程服务器上安装Web Deploy ,下载地址:http://www.iis.net/downloads/microsoft/web-deploy PS.安装时选择完全安装. 第二步: ...

  9. 移动端远程关闭PC端实现(一)需求设计

    公司有台半新不旧的电脑,因无甚大用,就拿来做了服务器,服务于民.服务器所提供的功能不是太多,无非是数据库以及svn服务. 公司每天下班会断电,我们吧会常常忘记关闭服务器,所以服务器非正常关机的次数约等 ...

  10. windows下adb+flash_image刷机

    刷机是常事,总要把刷机包放在卡上,然后关机三键一起按到recovery再刷,觉得不爽,麻烦,所以研究出了adb调用flash_image刷system分区,全部脚本windows脚本执行,点点鼠标就o ...