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 相关文章推荐
修复ie8&chrome下window的resize事件多次执行
Oct 20 Javascript
实例详解jQuery表单验证插件validate
Jan 18 Javascript
使用pcs api往免费的百度网盘上传下载文件的方法
Mar 17 Javascript
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
Jun 21 Javascript
javascript简单实现等比例缩小图片的方法
Jul 27 Javascript
canvas实现弧形可拖动进度条效果
May 11 Javascript
微信小程序--组件(swiper)详细介绍
Jun 13 Javascript
ligerUI---ListBox(列表框可移动的实例)
Nov 28 Javascript
vue配置接口域名方法总结
May 12 Javascript
Vue如何使用混合Mixins和插件开发详解
Feb 05 Javascript
Javascript地址引用代码实例解析
Feb 25 Javascript
Vue中Object.assign清空数据报错的解决方案
Mar 03 Vue.js
深入学习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+javascript实现二级级联菜单的制作
2008/05/06 PHP
使用PHP similar text计算两个字符串相似度
2015/11/06 PHP
php中的buffer缓冲区用法分析
2019/05/31 PHP
Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据
2009/08/09 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
BootStrap网页中代码显示用法详解
2016/10/21 Javascript
BootStrap3中模态对话框的使用
2017/01/06 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
Vue.js学习笔记之修饰符详解
2017/07/25 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
2018/01/20 Javascript
vue中设置height:100%无效的问题及解决方法
2018/07/27 Javascript
vue实现鼠标移入移出事件代码实例
2019/03/27 Javascript
javascript for循环性能测试示例
2019/08/07 Javascript
javascript实现移动端红包雨页面
2020/06/23 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
[00:14]护身甲盾
2019/03/06 DOTA
python实现调用其他python脚本的方法
2014/10/05 Python
详解Python3序列赋值、序列解包
2019/05/14 Python
Python安装与基本数据类型教程详解
2019/05/29 Python
ML神器:sklearn的快速使用及入门
2019/07/11 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
五分钟学会HTML5的WebSocket协议
2019/11/22 HTML / CSS
《纸船和风筝》教学反思
2014/02/15 职场文书
商务英语广告词大全
2014/03/18 职场文书
绩效管理实施方案
2014/03/19 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
纺织工程专业推荐信
2014/09/08 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
工作态度不好检讨书
2015/05/06 职场文书
个人道歉信大全
2019/04/11 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
MySql子查询IN的执行和优化的实现
2021/08/02 MySQL
浅谈Python3中datetime不同时区转换介绍与踩坑
2021/08/02 Python
Elasticsearch 聚合查询和排序
2022/04/19 Python
使用python绘制横竖条形图
2022/04/21 Python
ant design vue的form表单取值方法
2022/06/01 Vue.js