JavaScript_作用域(2017-03-16)

这里写的还不够清楚。

建议去看:王福朋 的博客的加深理解。

深入理解javascript原型和闭包(8)——简述【执行上下文】

深入理解javascript原型和闭包(9)——简述【执行上下文】下

深入理解javascript原型和闭包(10)——this

深入理解javascript原型和闭包(11)——执行上下文栈

深入理解javascript原型和闭包(12)——简介【作用域】

深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】

深入理解javascript原型和闭包(14)——从【自由变量】到【作用域链】

深入理解javascript原型和闭包(15)——闭包

深入理解javascript原型和闭包(16)——完结

后补:

深入理解javascript原型和闭包(17)——补this

深入理解javascript原型和闭包(18)——补充:上下文环境和作用域的关系

变量作用域

在JavaScript中全局变量的作用域比较简单,它的作用域是全局的,在代码的任何地方都是有定义的。然而函数的参数和局部变量只在函数体内有定义。另外局部变量的优先级要高于同名的全局变量,也就是说当局部变量与全局变量重名时,局部变量会覆盖全局变量(如下面例子)。

   var num = 1;            //声明一个全局变量
   function func() {
      var num = 2;        //声明一个局部变量
       return num;
   }
   console.log(func());    //输出:2 

 注:声明局部变量时一定要使用var,否则,解释器会将该变量当做全局对象window的属性。

函数作用域

在JavaScript中变量的作用域,并非和C、Java等编程语言似得,在变量声明的代码段之外是不可见的,我们通常称为块级作用域,然而在JavaScript中使用的是函数作用域(变量在声明它们的函数体以及这个函数体嵌套的任意函数体都是有定义的)。(如下面的例子)

 function func() {
            console.log(num);           //输出:undefined,而非报错,因为变量num在整个函数体内都是有定义的
            var num = 1;                //声明num 在整个函数体func内都有定义
            console.log(num);           //输出:1
        }
        func(); 

注:JavaScript的函数作用域是指在在函数内声明的所有变量在函数体内始终是可见的,也就是说在函数体内变量声明之前就已经可用了。

作为属性的变量

当声明一个全局变量的时候,实际上是定义了全局对象window的一个属性。

  var num = 1;            //声明全变量num
  alert(window.num)       //输出:1 声明的全局变量实际上就是声明了一个window对象的属性

作用域链

  在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]]。

  由ECMA-262标准第三版定义:该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

  当一个函数执行时,会创建此函数的作用域中可访问的数据对象的集合,填充变量对象的作用域链(scope chain,不简称sc)来保证对执行环境有权访问的变量和函数的有序访问。作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)

function a(x,y){
    var b=x+y;
    return b;
}

  在函数a创建的时候它的作用域链填入全局对象,全局对象中有所有全局变量

  如果执行环境是函数,那么将其活动对象(activation object, AO)作为作用域链第一个对象,第二个对象是包含环境,下一个是包含环境的包含环境。。。。。

function a(x,y){
    var b=x+y;
    return b;
}
var tatal=a(5,10);

这时候 var total=a(5,10);语句的作用域链如下

在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程,从第一个对象开始,逐级向后回溯,直到找到同名标识符为止,找到后不再继续遍历,找不到就报错。

* 如何创建新的作用域? 

可以利用function来创建新的作用域

alert(H1); //将得到函数的定义

alert(H2); //将出错,H2被定义到H1的内部,所以在H1的外部看不到这个变量

H1(); //可以执行,因为在这里能够看到H1

function H1(){

    alert(H2); //将得到函数的定义
    alert(H3); //将出错,H3被定义到H2的内部,所以在H2的外部看不到这个变量
    
    H2(); //可以执行,因为在这里可以看到H2
    function H2(){
        alert(H3); //将得到函数的定义
        function H3(){
        }
    }
}

 copy:

http://www.cnblogs.com/mrzl/p/4415149.html

http://www.cnblogs.com/dolphinX/p/3280876.html

原文地址:https://www.cnblogs.com/scevecn/p/6560788.html