JavaScript 作用域

1.作用域精讲

1.[[scope]]属性

  函数是全局的对象,每个对象都有属性,有一些属性可以被访问,有一些则不行,例如[[scope]]属性,属于隐式属性。 所说的作用域,存储着我们执行期上下文的集合。

2.运行期上下文

  当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行器上下文定义了一个函数执行时的环境,函数每次调用时都会新建一个执行期上下文,是独一无二的,多次调用创建多个,执行完即销毁。

function a(){
    //...
}
//a defined a[[scope]]--> 0 : GO(全局对象)
//a doing a[[scope]]--> 0 : A0
//                1 : GO

3.查找变量

  从作用域链的顶部开始依次向下执行。

4.闭包

当内部函数被保存到外部函数时,将会产生闭包。闭包导致原有的作用域链不释放,造成内存泄露

 1 function a(){
 2     var aa=123;
 3     function b(){
 4         a--;
 5         console.log(a);
 6     }
 7     return b;
 8 }
 9     var demo=a();   //a执行完的return b函数给 demo;
10     demo(); // b执行
11 // a defined  a[[scope]] --> 0 : GO
12 13 // b defined  b[[scope]] --> 0 : AO
14 //                           1 : GO
15 16 //a doing   a[[scope]] -->  0 : AO
17 //                          1 : GO

 

b[[scope]]如下:

  

  

 

//输出结果 10 10 10 10 10 10 10 10 10 10
//要想输出 0 1 2 3 4 5...
function test(){
    var arr=[];
    for(var i=0;i<10;i++){
      //闭包
        (function (j){
            //j= i;
            var arr[i] = function (){
                document.write(j+' ');
            }
        }(i));      //立即执行函数,
    }
    return arr;
}
var myArr = test();
for(var j = 0;j < 10; j++){
    myArr[i]();
}
​
//10个立即执行函数
分别指向不同的 -->  AO;

 

5.闭包的作用

  1. 实现公有变量 eg:累加器


function a(){
    var count=0;
    function b(){
        count++;
        console.log(count);
    }
  return b;
}
var demo=a();
demo();  // 1
demo();  // 2

 

  1. 可以做缓存(存储结构) eg:eater

  1. 可以实现封装,属性私有化。 eg : person()


  2. Deng函数运行完变量销毁,但与里面的函数形成闭包,通过作用域链找到

4.模块化开发,防止污染全局变量,使用于模块化开发 (命名空间)

  防止变量冲突问题

    1.传统方法

      

    2.闭包和立即执行函数

      

运用立即执行函数,在函数中定义私有属性。与内部函数形成闭包,再return 一个函数

函数内部有函数接口。 

 

posted @ 2017-10-13 13:21  im.lhc  阅读(139)  评论(0编辑  收藏  举报