首页 > 网站 > WEB开发 > 正文

作用域,作用域链,闭包

2024-04-27 15:18:19
字体:
来源:转载
供稿:网友

闭包、作用域、作用域链

一 作用域,作用域链

先上代码

复制代码
1 var scope="global";  2 function t(){  3     console.log(scope);  4     var scope="local"  5     console.log(scope);  6 }  7 t();  复制代码

此时打印出来的 按顺序分别是undefine,local,为什么第一个是undefined呢,摘抄下js作用域原话:

javascript没有块级作用域,而是函数作用域.

所谓函数作用域就是说:-》变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

所以此段代码就可以解释为:

复制代码
var scope="global";   function t(){     var scope;      console.log(scope);       scope="local"       console.log(scope);   }   t();  复制代码

所以明显看出来第一句打印,只是重新声明了变量,而没有赋值

 

二 闭包与this

在闭包中使用this对象会出现一些问题,this对象是运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被当作某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行环境具有全局性,因此其this对象通常指向window(当然,在通过call()和apply()改变函数执行环境时,this指向其他对象)。

复制代码
var name="The Window";      var object={      name:"My object",      getNameFunc:function(){          return function(){              return this.name;              };          }      };  alert(object.getNameFunc()()); //"The Window"(在非严格模式下)此时弹出  The Window复制代码

如果要改变,那么我自己的理解就是让闭包能 根据活动函数上下文找到 外部函数的变量,那么就把this重新赋值给一个变量

复制代码
var name="The Window";      var object={      name:"My object",      getNameFunc:function(){      var that = this;        return function(){              return that.name;              };          }      };  alert(object.getNameFunc()()); //"The Window"(在非严格模式下)此时弹出  My object复制代码

 

三 闭包的内存释放与执行规则

直接上代码

复制代码
function fun03()        {            var a = 10;            return function(){                a*= 2 ;                return a ;            };        }          var f = fun03();        f();        var x = f();       console.log(x);  //40          var g = fun03();        var y = g();        console.log(y); //20 复制代码

为什么第一句打印的是40,第二句打印20呢,目测看到的原因是第一句打印  f()执行了两次(但是函数一旦执行后那么里面的局部变量就会销毁,但是为什么没有被销毁呢,这就是闭包的作用)

因为闭包可以使变量不被释放,始终存在内存中,因为fun03是其中匿名函数(闭包)的父函数,而匿名函数又被赋值给了一个全局变量,所以f一直在内存中,而f又依赖于fun03所以这就导致其中的a变量一直存在,当运行两次后a进行了累加计算

结合垃圾回收机制来理解作用域链


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表