热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

js闭包用法实例详解

这篇文章主要介绍了js闭包用法,结合实例形式分析了JS闭包的概念、功能及相关操作技巧,需要的朋友可以参考下

本文实例讲述了js闭包用法。分享给大家供大家参考,具体如下:

引言

在公司中需要写一个js脚本来进行网站的统计,实现类似百度统计或者站长统计的功能,在实现的过程中自己感觉写的代码还是可以的,因为之前的js代码都是这些写,但是在组长代码走查的时候却非常的不满意,因为我们在js中写的方法都是全局的方法,因为我们写的东西需要嵌入到别人的界面中,所以这些全局的东西很可能会和别人的东西重名从而引发错误,所以说组长就给我留下一句话:用js闭包包起来。

变量作用域

我们都非常的熟悉变量的作用域就分为:全局变量和局部变量。js中在函数的内部可以直接读取全局变量。

Js代码

var n=999;
function f1(){
  alert(n);
}
f1(); // 999

另一方面,在函数外部自然无法读取函数内的局部变量。

Js代码

function f1(){
  var n=999;
}
alert(n); // error

我们还需要注意,在js中如果声明变量的时候一定要用var命令,否则实际上声明了一个全局的变量!

function f1(){
  n=999;
}
f1();
alert(n); // 999

如何从外部读取全局变量?

我们需要得到函数内部的全局变量该怎么办呢?。在正常情况下我们是做不到的,要想这么实现我们必须想一些办法——在函数的内部在定义一个函数:

function f1(){
  n=999;
  function f2(){
    alert(n); // 999
  }
}

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

function f1(){
  n=999;
  function f2(){
    alert(n);
  }
  return f2;
}
var result=f1();
result(); // 999

闭包的概念

在上面的代码中f2函数,就是闭包。各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

下面来分享一下我们在项目中用到的js闭包的写法:

(function () {
  function getPageTitle() {
    return document.title;
  }
  function getBrowerLanguage() {
    var browerLanguage = !navigator.browserLanguage ? navigator.language : navigator.browserLanguage;
    return browerLanguage;
  }
  /**
   * 当前页面地址#后的部分
   */
  function getLastUrl() {
    var url = window.location.hash;
    if (!url) {
      return null;
    }
    else {
      return url.toString().split("#")[1];
    }
  }
  function GetRandomNum() {
    var arr = document.COOKIE.match(new RegExp("(^| )" + "statisticssCOOKIE=([^;]*)(;|$)"));
    if (arr != null) {
      return arr[2];
    } else {
      var tempRandomNum = guid();
      document.COOKIE = "statisticssCOOKIE = " + tempRandomNum;
      return tempRandomNum;
    }
  }
  function guid() {
    function S4() {
      return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }
    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  }
  function addJs() {
    var url = "http://localhost:10086/tongji/tongji/do?title=" + getPageTitle() + "&browerLanguage=" + getBrowerLanguage() + "&lastUrl=" + getLastUrl() + "&upFlag=" + GetRandomNum();
    var head = document.getElementsByTagName('head')[0];
    var js = document.createElement('script');
    js.type = 'text/Javascript';
    js.src = url;
    head.appendChild(js);
  }
  window.statistics = addJs;//将addJs这个方法挂在window下面,这样在外界是可以访问的,否则外界永不能访问到我写的方法
  document.ready = addJs();//DOM树加载完成后执行
})(window)

小结

在开始的时候组长就问我会不会js闭包函数,因为如果不会闭包写不出很好的代码。写的代码都非常的粗糙,所以说我们在写代码的时候,不能仅仅满足功能实现,而且需要考虑一些其他方面的东西。当然js闭包在使用的时候也有一些弊端,所以我们在使用的时候也需要综合全面的信息考虑。

更多关于Javascript相关内容感兴趣的读者可查看本站专题:《Javascript数据结构与算法技巧总结》、《Javascript数学运算用法总结》、《Javascript切换特效与技巧总结》、《Javascript查找算法技巧总结》、《Javascript错误与调试技巧总结》及《Javascript遍历算法与技巧总结》

希望本文所述对大家Javascript程序设计有所帮助。


推荐阅读
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • HTML5网页模板怎么加百度统计?
    本文介绍了如何在HTML5网页模板中加入百度统计,并对模板文件、css样式表、js插件库等内容进行了说明。同时还解答了关于HTML5网页模板的使用方法、表单提交、域名和空间的问题,并介绍了如何使用Visual Studio 2010创建HTML5模板。此外,还提到了使用Jquery编写美好的HTML5前端框架模板的方法,以及制作企业HTML5网站模板和支持HTML5的CMS。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 【影评】大内密探灵灵狗
    本文是对王晶执导的电影《大内密探灵灵狗》进行的影评。文章称赞了王晶的才华和导演经验,认为演员阵容强大,笑料不少,发明新奇又好笑。然而,编剧的表现被认为是本片的最大失败,宣传言过其实,笑点不多。总体来说,本片是一部典型的王式喜剧,可看性较高,但没有突破。 ... [详细]
  • Iwouldliketobeabletohaveasidebarthatcanbetoggledinandoutonabuttonpress.However ... [详细]
  • JavaScript在常人看来都是门出不了厅堂的小语言,仅管它没有明星语言的闪耀,但至少网页的闪耀还是需要它的,同时它是一门很实用的语言,本人平时就喜欢拿它来写点实用工具或应用,本文演示用JavaSc ... [详细]
  • ImgettingabugwithInternetExplorer.Theiframedoesnthavecorrectsizeanditisdisplayedo ... [详细]
  • 我试图制作一个进度条,如果还有更多内容仍被隐藏,则显示箭头。为了更清楚,我做 ... [详细]
  • IntheBestPracticestoimprovewebsitePerformancehttp:developer.yahoo.comperformancerules.h ... [详细]
author-avatar
悍受蓁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有