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

第二话:javascript中闭包的理解

2024-04-27 14:22:25
字体:
来源:转载
供稿:网友

第二话:javascript中闭包的理解

2014-06-22 00:29 by JerryXin, ... 阅读, ... 评论, 收藏, 编辑

闭包是什么?

通过闭包,子函数得以访问父函数的上下文环境,即使父函数已经结束执行。

OK,我来简单叙述下,先上图。

window

都知道函数是Javascript整个世界,对象是函数,方法是函数,并且js中实质性的面向对象相关也都是函数来实现和延伸,例如:“类”。

window:是指js中window对象,也是js最高一层,因为什么这么说,因为你所有创建的方法和属性其实都在window之内。window中的所有方法,在手动创建的方法中都可以调到。可以仔细想想alert,在任何地方都可以alert,其实alert就是window内部的一个方法。window.alert()。具体参看:JavaScript Window - 浏览器对象模型

回到图上:

那么我创建的每一个全局function其实都是window的方法,所以window把a()和b()包含;但d()和e()呢?他们是局部的。a()包含d(),b()包含e();由此推出下面代码:

function window(){                 //虚构出来的,只为说明问题,因为window属于浏览器内置类,所以根本看不到    function a(){        var a = 1;        function d(){            var d = 3;            alert(a+d); //4                    }    }    function b(){        var b = 1;        function e(){            var e = 4;            alert(b+e);    //5        }    }}

其实闭包的概念已经包含在这个函数中,d()中可以访问a()中定义的a变量和window中声明的所有变量和函数,e()中可以访问b()中的b变量和window中声明的所有变量和函数。

完毕。

闭包中最常见的用途是声明事件处理器和匿名空间使用:

声明事件处理器

function a(){     var obj = document.getElementById("text");     obj.onclick = function(){ obj.innerHTML = " hello world!"};}

绑定到onclick上的函数建立了一个闭包,所以它能访问obj变量。

function a(){     var obj = document.getElementById("text");     obj.onclick = clickHandler;}function clickHandler(){    function(){ obj.innerHTML = " hello world!"};}

clickHandler并不能访问到obj,因为clickHandler定义在a()外部。

闭包引用可以避免this调用造成的恐慌。

function launcher(element,message){    function openWin(){        alert(message);    }    window.addEventListener("click",element,false);}launcher("document.getElementById("text")","hello world!");

匿名空间:

在js组件开发之中,如果涉及到无穷多的组件加载,那命名冲突不可避免。

例如:

//组件1var abc = 5;function TabView(cfg){     this.a = cfg.a;    this.b = cfg.b;}TabView.PRotype = {    c:function(){ abc++;};    d:function(){abc--};}//组件2var abc = 100;function TreeView(cfg){     this.a = cfg.a;    this.b = cfg.b;}TreeView.protype = {    c:function(){ abc*=2;};    d:function(){abc/=2;};}

如果一个项目同时需要加载这两个组件,那么就会出现命名冲突;因此我们需要来避免这种问题,通过采用匿名空间-----闭包的办法;

//组件1(function (){    var abc = 5;    function TabView(cfg){             this.a = cfg.a;            this.b = cfg.b;    }    TabView.protype = {            c:function(){ abc++;};            d:function(){abc--};    }    window.TabView = TabView;              //将TabView类公开(作用域在window下)。除该类以外所有匿名空间内部定义,都对外界不形成干扰;})();//组件2(function (){    var abc = 100;    function TreeView(cfg){        this.a = cfg.a;        this.b = cfg.b;    }    TreeView.protype = {            c:function(){ abc*=2;};            d:function(){abc/=2;};    }    window.TreeView = TreeView;              //将TabView类公开(作用域在window下)。除该类以外所有匿名空间内部定义,都对外界不形成干扰;})()外部调用的时候只需:    var tabView = new TabView();    var treeView = new TreeView();

ok,细细回味,闭包会带来很多方便……


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