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 相关文章推荐
基于jquery的监控数据是否发生改变
Apr 11 Javascript
使用js如何实现全选与全不选
Dec 30 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 Javascript
微信公众平台开发教程(四) 实例入门:机器人回复(附源码)
Dec 02 Javascript
js实现小窗口拖拽效果
Dec 03 Javascript
用js屏蔽被http劫持的浮动广告实现方法
Aug 10 Javascript
vue自定义filters过滤器
Apr 26 Javascript
微信小程序实现登录遮罩效果
Nov 01 Javascript
vue实现的微信机器人聊天功能案例【附源码下载】
Feb 18 Javascript
Vue项目服务器部署之子目录部署方法
May 12 Javascript
JS前端面试必备——基本排序算法原理与实现方法详解【插入/选择/归并/冒泡/快速排序】
Feb 24 Javascript
Vue将props值实时传递 并可修改的操作
Aug 09 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
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
第五节--克隆
2006/11/16 PHP
解析MySql与Java的时间类型
2013/06/22 PHP
PHP中使用循环实现的金字塔图形
2014/11/08 PHP
javascript中字符串拼接需注意的问题
2010/07/13 Javascript
php 中序列化和json使用介绍
2013/07/08 Javascript
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
jQuery分别获取选中的复选框值的示例
2014/06/17 Javascript
nodejs之请求路由概述
2014/07/05 NodeJs
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2015/04/01 Javascript
分享网页检测摇一摇实例代码
2016/01/14 Javascript
[js高手之路]寄生组合式继承的优势详解
2017/08/28 Javascript
vue组件编写之todolist组件实例详解
2018/01/22 Javascript
Nuxt页面级缓存的实现
2020/03/09 Javascript
angular组件间通讯的实现方法示例
2020/05/07 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
python开发之str.format()用法实例分析
2016/02/22 Python
python 采集中文乱码问题的完美解决方法
2016/09/27 Python
Python之str操作方法(详解)
2017/06/19 Python
python实现批量注册网站用户的示例
2019/02/22 Python
Python实现性能自动化测试竟然如此简单
2019/07/30 Python
python中图像通道分离与合并实例
2020/01/17 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
Joe Fresh官网:加拿大时尚品牌和零售连锁店
2016/11/30 全球购物
Vince官网:全球著名设计师品牌,休闲而优雅的服饰
2017/01/15 全球购物
Blue Nile台湾:钻石珠宝商,订婚首饰、结婚戒指和精品首饰
2017/11/24 全球购物
巴黎一票通:The Paris Pass
2018/02/10 全球购物
Under Armour瑞典官方网站:美国高端运动科技品牌
2018/11/21 全球购物
be2台湾单身男女交友:全球网路婚姻介绍的领导品牌
2019/10/11 全球购物
自动化专业毕业生自荐信
2013/11/01 职场文书
2014年教师政治学习材料
2014/06/02 职场文书
学习十八大标语
2014/10/09 职场文书
离婚协议书范文2014
2014/10/16 职场文书
会计师事务所实习证明
2014/11/16 职场文书
邀请函模板
2015/02/02 职场文书
工作时间证明
2015/06/15 职场文书