js闭包用法实例详解


Posted in Javascript onDecember 13, 2016

本文实例讲述了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 简单高效判断数据类型 系列函数 By shawl.qiu
Mar 06 Javascript
向当前style sheet中插入一个新的style实现方法
Apr 01 Javascript
JavaScript学习小结(7)之JS RegExp
Nov 29 Javascript
js获取时间精确到秒(年月日)
Mar 16 Javascript
JS实现保留n位小数的四舍五入问题示例
Aug 03 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
Nov 11 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
Dec 12 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
Feb 10 Javascript
解决AngualrJS页面刷新导致异常显示问题
Apr 20 Javascript
JS获取子节点、父节点和兄弟节点的方法实例总结
Jul 06 Javascript
vue实现拖拽的简单案例 不超出可视区域
Jul 25 Javascript
手写实现JS中的new
Nov 07 Javascript
深入学习Bootstrap表单
Dec 13 #Javascript
ThinkJS中如何使用MongoDB的CURD操作
Dec 13 #Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 #Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
Dec 13 #Javascript
教大家轻松制作Bootstrap漂亮表格(table)
Dec 13 #Javascript
AngularJS自定义控件实例详解
Dec 13 #Javascript
Node.js中process模块常用的属性和方法
Dec 13 #Javascript
You might like
PHP对象Object的概念 介绍
2012/06/14 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
PHP实现格式化文件数据大小显示的方法
2015/01/03 PHP
PHP实现的下载远程图片自定义函数分享
2015/01/28 PHP
PHP面向对象中new self()与 new static()的区别浅析
2017/08/17 PHP
Laravel5.4框架使用socialite实现github登录的方法
2019/03/20 PHP
用PHP做了一个领取优惠券活动的示例代码
2019/07/05 PHP
js post提交调用方法
2014/02/12 Javascript
js 触发select onchange事件代码
2014/03/20 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
jquery如何扑捉回车键触发的事件
2014/04/24 Javascript
JavaScript基于自定义函数判断变量类型的实现方法
2016/11/23 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
2017/03/01 Javascript
详解vue与后端数据交互(ajax):vue-resource
2017/03/16 Javascript
Vue在 Nuxt.js 中重定向 404 页面的方法
2019/04/23 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
微信小程序实现二维码签到考勤系统
2020/01/16 Javascript
[01:04:35]2018DOTA2亚洲邀请赛 4.3 突围赛 Secret vs VG 第一场
2018/04/04 DOTA
python使用cookielib库示例分享
2014/03/03 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python编程把二叉树打印成多行代码
2018/01/04 Python
浅谈python脚本设置运行参数的方法
2018/12/03 Python
python多线程下信号处理程序示例
2019/05/31 Python
python实现简易学生信息管理系统
2020/04/05 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
Python requests接口测试实现代码
2020/09/08 Python
利用CSS3实现折角效果实例源码
2016/09/28 HTML / CSS
澳大利亚波西米亚风连衣裙在线商店:Fortunate One
2019/04/01 全球购物
cf收人广告词
2014/03/14 职场文书
社区服务活动小结
2014/07/08 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
观看《杨善洲》宣传教育片心得体会
2016/01/23 职场文书
golang在GRPC中设置client的超时时间
2021/04/27 Golang
python超详细实现完整学生成绩管理系统
2022/03/17 Python
CentOS7环境下MySQL8常用命令小结
2022/06/10 Servers