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 相关文章推荐
封装好的省市地区联动控件附下载
Aug 13 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
js基本算法:冒泡排序,二分查找的简单实例
Oct 08 Javascript
微信小程序 闭包写法详细介绍
Dec 14 Javascript
javascript基于原型链的继承及call和apply函数用法分析
Dec 15 Javascript
jquery实现tab键进行选择后enter键触发click行为
Mar 29 jQuery
jquery Ajax实现Select动态添加数据
Jun 08 jQuery
javascript cookie的基本操作(添加和删除)
Jul 24 Javascript
JS动态添加的div点击跳转到另一页面实现代码
Sep 30 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
使用vue-cli导入Element UI组件的方法
May 16 Javascript
微信小程序页面间值传递的两种方法
Nov 26 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 ADODB使用方法集锦
2008/03/25 PHP
基于php缓存的详解
2013/05/15 PHP
ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单
2014/05/15 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
2014/06/19 PHP
PHP中常用的输出函数总结
2014/09/22 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
ThinkPHP实现更新数据实例详解(demo)
2016/06/29 PHP
js form action动态修改方法
2008/11/04 Javascript
JS模拟的QQ面板上的多级可展开的菜单
2009/10/10 Javascript
JS中自定义定时器让它在某一时刻执行
2014/09/02 Javascript
使用js Math.random()函数生成n到m间的随机数字
2014/10/09 Javascript
JavaScript 节流函数 Throttle 详解
2016/07/04 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
2017/08/28 Javascript
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
基于bootstrap写的一点localStorage本地储存
2017/11/21 Javascript
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
2020/01/04 Javascript
微信小程序如何实现点击图片放大功能
2020/01/21 Javascript
vue实现购物车列表
2020/06/30 Javascript
解决vue-router路由拦截造成死循环问题
2020/08/05 Javascript
[41:41]TFT vs Secret Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
python实现斐波那契递归函数的方法
2014/09/08 Python
python 判断是否为正小数和正整数的实例
2017/07/23 Python
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
微信小程序python用户认证的实现
2019/07/29 Python
Python  Django 母版和继承解析
2019/08/09 Python
Python Numpy 自然数填充数组的实现
2019/11/28 Python
Python模块future用法原理详解
2020/01/20 Python
AUC计算方法与Python实现代码
2020/02/28 Python
Window系统下Python如何安装OpenCV库
2020/03/05 Python
Python 读取WAV音频文件 画频谱的实例
2020/03/14 Python
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
AJAX都有哪些有点和缺点
2012/11/03 面试题
儿科护理实习自我鉴定
2013/09/19 职场文书
详解Vue的options
2021/05/15 Vue.js