相关定义

  • 引擎:从头到尾负责整个JavaScript程序的编译及执行过程。
  • 编译器:负责语法分析及代码生成等。
  • 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

  引擎会调用编译器对源代码进行编译,其中编译器编译过程中遇到变量声明会将其添加到当前作用域中,引擎执行编译过后的代码,遇到变量时会去作用域查找。

总结

  1. 当程序中含有var a = 2时,会分为“var a; a = 2;”两个部分:①首先是编译器查看作用域,如果作用域已含有a则忽略该声明(var a;)继续编译,否则会要求作用域在当前的集合中声明一个新的命名为a的变量(该步骤在代码执行前执行)。②编译器为引擎生成运行处理a = 2所需的代码,引擎运行该代码时会在当前的作用域集合中查看是否有a,如果有的话会使用这个变量,没有的话则会继续查找。  (ps:因为在编译执行前将变量a加入作用域中,所以即使在声明a之前调用它也不会报错,因为当前作用域中已含有它,只不过执行到赋值语句前为undefined,这也就是通常所说的声明提前。)

    //不会报错,因为在编译执行之前,f 函数的上级作用域中已含有变量a的声明,所以运行时会弹出undefined。
    window.onload = function(){
    function f(){
    alert(a);
    }
    f();
    var a = 0;
    }
  2. 引用类型:LHS和RHS,即赋值操作的左侧和右侧(也可理解为对变量赋值和使用变量的值)。因为对于引擎来说,它对于赋值和调用会对该次变量引用执行不同的操作,所以需要区分。LHS即类似a = 2,function f(a){...}中的a(被赋值),RHS即a = b + 2;console.log(b)中的b(被调用)
  3. 作用域是一层一层嵌套的,当引擎没有在当前作用域中查找到该变量时,它会向该作用域的上一层作用域继续查找,最上层为全局作用域,再没有找到则会报ReferenceError异常。如图,则会报错,因为作用域只能向上查找。
    //会报错,因为作用域只会向上查找
    window.onload = function(){
    function f(){
    var a = 0;
    } alert(a);
    }
  4. 有一种特殊情况:在非严格模式下(无"use strict"),当变量为LHS且未声明时(即未声明就赋值),全局作用域会自动创建该变量并返回给引擎(这就是为什么在函数中不声明直接赋值,这个变量会变为全局变量),开启严格模式后则不会自动创建,报Referenct错误。如下:

    //当未开启严格模式时,会弹出3
    // "use strict";
    window.onload = function(){
    a = 3;
    alert(a);
    }

    开启(取消“use strict”注释)后,则会报错:

ps:RHS(未声明就调用)引用时会直接报错。

5. 如果找到变量对变量的值进行不合理的操作,比如试图对一个非函数类型变量进行函数调用,则会报TypeError异常。

相关例子:

  在网上搜罗了一些类似的例子,分享给大家,加深理解:

//输出为number和undefined
<script type="text/javascript">
var a = 1;
var a;
alert(typeof a); (function () {
b = '-----';
var b;
})();
alert( typeof b);
</script>

//输出为undefined和string
<script type="text/javascript">
name="aaa";
function test(){
alert(typeof name); var name="bbb";
alert(typeof name);
}
test();
</script> //输出 1,undefined,2
x = 1;
alert(x);
var y = function() {
  alert(x);
  var x = 2;
  alert(x);
}
y();
 

今天就写到这里啦,感觉看完第一章作用域的讲解真的是受益匪浅,希望对你也有一定的启发~。

  

《你不知道的js》 ------1.作用域是什么的更多相关文章

  1. 你不知道的JS之作用域和闭包 附录

     原文:你不知道的js系列 A 动态作用域 动态作用域 是和 JavaScript中的词法作用域 对立的概念. 动态作用域和 JavaScript 中的另外一个机制 (this)很相似. 词法作用域是 ...

  2. 你不知道的JS之作用域和闭包(五)作用域闭包

    原文:你不知道的js系列 一个简单粗暴的定义 闭包就是即使一个函数在它所在的词法作用域外部被执行,这个函数依然可以访问这个作用域. 比如: function foo() { var a = 2; fu ...

  3. 你不知道的JS之作用域和闭包(四)(声明)提升

    原文:你不知道的js系列 先有鸡还是先有蛋? 如下代码: a = 2; var a; console.log( a ); 很多开发者可能会认为结果会输出 undefined,因为 var a 在 a ...

  4. 你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域

      原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到 ...

  5. 你不知道的JS之作用域和闭包(二)词法作用域

    原文:你不知道的js系列 词法作用域(Lexical Scope) Lex time 一个标准的编译器的第一个阶段就是分词(token化) 词法作用域就是在词法分析时定义的作用域.换句话说,词法作用域 ...

  6. 你不知道的JS之作用域和闭包(一)什么是作用域?

    原文:你不知道的js系列 什么是作用域(Scope)? 作用域 是这样一组规则——它定义了如何存放变量,以及程序如何找到之前定义的变量. 编译器原理 JavaScript 通常被归类为动态语言或者解释 ...

  7. 翻译连载 | 第 10 章:异步的函数式(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  8. 翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  9. JS 函数作用域及变量提升那些事!

    虽然看了多次js函数作用域及变量提升的理论知识,但小编也是一知半解~ 这几天做了几道js小题,对这部分进行了从新的理解,还是有所收获的~ 主要参考书籍: <你不知道的JavaScript(上卷) ...

  10. 翻译连载 | 第 11 章:融会贯通 -《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

随机推荐

  1. 用apache配置多个tomcat webapp

    The Apache HTTP Server Project is an effort to develop and maintain an open-source HTTP server for m ...

  2. springMVC注解及优化

    1. 新建web project 2. 添加jar 3. 改写web.xml, 注意spring-servlet.xml的名字 <?xml version="1.0" enc ...

  3. php script 的生命周期

    原文地址:https://support.cloud.engineyard.com/hc/en-us/articles/205411888-PHP-Performance-I-Everything-Y ...

  4. 使用bootstrap响应式布局——手机屏幕中横向滚动显示标签页选项

    导航栏到小屏幕的时候,我们的处理办法是隐藏为一个按钮.可是选项卡的标签页部分,我们的处理办法是加一个水平滚动条.但是加水平滚动条需要解决一个问题,就是宽度的问题,如果不设置宽度,他就会根据屏幕大小自适 ...

  5. bootstrap建立响应式网站——tab选项卡

    1.bootstrap给我们提供了标签页 细细看了一下bootstrap的标签页源码,对tab选项卡有了更深的理解.其实说来也简单,以前自己写js和css时没有意识到整体的划分.就是分为两部分:一部分 ...

  6. mysql、mysqli、pdo使用

    一.php手册关于MySQL的说明:    This extension is not recommended for writing new code. Instead, either themys ...

  7. (简单) POJ 1860 Currency Exchange,SPFA判圈。

    Description Several currency exchange points are working in our city. Let us suppose that each point ...

  8. JAVA基础--适配器模式

    interface Window{ // 定义Window接口,表示窗口操作 public void open() ; // 打开 public void close() ; // 关闭 public ...

  9. 调用图灵机器人API实现Android智能机器人

    非常感谢CSDN博客上的鸿洋哥,他贴出的源码是我所做的工作的基础,鸿洋哥博客链接http://blog.csdn.net/lmj623565791/article/details/38498353 下 ...

  10. Redis详解

    转自:http://blog.csdn.net/eroswang/article/details/7080412 1.  MySql+Memcached架构的问题 1.MySQL需要不断进行拆库拆表, ...