您的位置:首页 > 其它

关于作用域、防止作用域污染、作用域链和闭包的理解

2018-09-27 16:29 260 查看

参考博客:https://www.geek-share.com/detail/2704474670.html

作用域

变量的作用域无非就是两种:全局作用域和局部作用域。 
全局作用域: 
最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:

[code]   <script>
var outerVar = "outer";
function fn(){
console.log(outerVar);
}
fn();//result:outer
</script>

局部作用域: 
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部

[code]<script>
function fn(){
var innerVar = "inner";
}
fn();
console.log(innerVar);// ReferenceError: innerVar is not defined
</script>

 需要注意的是,函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上声明了一个全局变量!

以下是一个重要的特性!!

只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”,举例:

[code]   <script>
var scope = "global";
function fn(){
console.log(scope);//result:undefined
var scope = "local";
console.log(scope);//result:local;
}
fn();
</script>

第一个输出居然是undefined,原本以为它会访问外部的全局变量(scope=”global”),但是并没有。这可以算是javascript的一个特点,只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”。

[code]   <script>
var scope = "global";
function fn(){
var scope;//提前声明了局部变量
console.log(scope);//result:undefined
scope = "local";
console.log(scope);//result:local;
}
fn();
</script>

但是javascript不同,并没有所谓的块级作用域,javascript的作用域是相对函数而言的,可以称为函数作用域:

[code]   <script>
for(var i = 1; i < 10; i++){
//coding
}
console.log(i); //10
</script>

防止作用域污染

在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题, 尽量避免全局变量。

可采取两种措施:

一是定义全局变量命名空间,只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下

[code]var MY={};
my.name={
big_name:"zhangsan",
small_name:"lisi"
};
my.work={
school_work:"study",
family_work:"we are"
};

 二 是利用匿名函数将脚本包裹起来

[code](function(){
var exp={};
var name="aa";
exp.method=function(){
return name;
};
window.ex=exp;
})();

作用域链(Scope Chain)

那什么是作用域链? 
我的理解就是,根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。 
想要知道js怎么链式查找,就得先了解js的执行环境

执行环境(execution context)

js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中。 

js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。 

[code]   <script>
var scope = "global";
function fn1(){
return scope;
}
function fn2(){
return scope;
}
fn1();
fn2();
</script>

上面代码执行情况演示: 

闭包

其实闭包也就是指有权访问另一个函数作用域的函数而已。常用的创建闭包的方法就是在函数内部创建另一个函数。

闭包有两个作用: 
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找) 
第二个就是让这些外部变量始终保存在内存中 (容易导致内存泄漏)

关于this对象

关于闭包经常会看到这么一道题:

[code]  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());//result:The Window

 《javascript高级程序设计》一书给出的解释是:

this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window。

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: