匿名函数自我调用_自调用匿名函数(匿名闭包)解析与调用

打开jQuery源码,首先你会看到这样的代码结构:

(function(window,undefined ){//})();

这是一个自调用匿名函数。什么东东呢?在第一个括号内,创建一个匿名函数;第二个括号,立即执行

为什么要创建这样一个“自调用匿名函数”呢?

通过定义一个匿名函数,创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏全局的命名空间。这点非常有用也是一个JS框架必须支持的功能,jQuery被应用在成千上万的JavaScript程序中,必须确保jQuery创建的变量不能和导入他的程序所使用的变量发生冲突。

接下来看看在 自调用匿名函数 中都实现了什么功能,按照代码顺序排列:

(function( window, undefined ) {//构造jQuery对象

var jQuery = function( selector, context ) {return newjQuery.fn.init( selector, context, rootjQuery );

}//工具函数 Utilities//异步队列 Deferred//浏览器测试 Support//数据缓存 Data//队列 queue//属性操作 Attribute//事件处理 Event//选择器 Sizzle//DOM遍历//DOM操作//CSS操作//异步请求 Ajax//动画 FX//坐标和大小

window.jQuery = window.$ =jQuery;

})(window);

匿名函数从语法上叫函数直接量,JavaScript语法需要包围匿名函数的括号,事实上自调用匿名函数有两种写法:

(function() {

console.info(this);

console.info( arguments );

}( window ) );

(function() {

console.info(this);

console.info( arguments );

})( window );

经常使用的方法如下格式:

(function($, owner){//登录

owner.login = function(info,callback){//code

};//注册

owner.reg = function(name,callback){//code

};

}(jQuery, window.app={}));

调用:

app.login(info,function(){});

app.reg(name,function(){})

为什么要传入window呢?

通过传入window变量,使得window由全局变量变为局部变量,当在jQuery代码块中访问window时,不需要将作用域链回退到顶层作用域,这样可以更快的访问window;这还不是关键所在,更重要的是,将window作为参数传入,可以在压缩代码时进行优化,看看jquery-1.6.1.min.js: (function(a,b){})(window); // window 被优化为 a

通过以上的介绍,我们大概了解通过()可以使得一个函数表达式立即执行。

匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,

所以 ( function(){…} )() 内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

(function() {//... 所有的变量和function都在这里声明,并且作用域也只能在这个匿名闭包里//...但是这里的代码依然可以访问外部全局的对象

}());

同下面

(function () {/*内部代码*/})();

通俗的讲,()就是用来求值的,因此这个()任何时候都不能为空,因为它是要计算的。函数解析它只会解析到 {}为止,不会解析到 ()的。

把表达式放在()中会返回表达式的值;

把函数放在()中会返回函数本身;(function(){}());

如果()紧跟在函数后面,就是表示在调用函数,即对函数求值:(function(){})();

(function() {//自执行函数中的内部变量,外部是无法访问的

var name = 'kevin';

})( window );

name//undefined,无法获取name的值

代码在运行过程中,会优先解析 【巳声明的函数】;

而函数表达式是当执行到它时,才会解析;

匿名函数是不会单独写的,因此它的执行是需要其它函数的调用,通常看到的匿名函数,都是当作参数被传递的。而立即执行函数它本身就是个匿名函数,

js代码执行的顺序://巳声明的函数 function test(){}//匿名函数 function (){}//函数表达式 var test = function(){}//立即执行函数 (function(){})();

立即执行函数配合闭包,在模块化中的应用,其中要明白几个点:

1、要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明;

2、立即执行函数可以当作是一个私有作用域,作用域内部可以访问外部的变量,而外部环境是不能访问作用域内部的变量的,因此,立即执行函数是一个封闭的作用域,不会和外部作用域起冲突。

JQuery使用的就是这种方法,将JQuery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用JQuery代码时,可以达到保护JQuery内部变量的作用。

3、Module模式,是自执行函数的高级模式,可以非常方便的在各个匿名闭包中以全局对象调用闭包函数。有兴趣可以查看:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html Module 模式为:

a.创建一个立即调用的匿名函数表达式

b.return一个变量,其中这个变量里包含你要暴露的东西

c.返回的这个变量将赋值给window

(function() {var i = 0;return{

get:function() {returni;

},

set:function(val) {

i=val;

},

increment:function() {return ++i;

}

};

} (window));//window作为一个带有多个属性的全局对象,上面的代码对于属性的体现其实是方法,它可以这样调用:

window.get(); //0

window.set(3);

window.increment();//4

window.increment(); //5

window.i;//undefined 因为i不是返回对象的属性

i; //引用错误: i 没有定义(因为i只存在于闭包)

/******上面就是关于自调用匿名函数的解析,那么这样的函数它是怎么被调用的呢?*******/

/******下面是关于全局变量的调用,也就是匿名闭包函数的调用*******/

再次搬出Module模式,有兴趣可以查看:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html

Module 模式,也就是匿名闭包的创建与调用:

a.创建一个立即调用的匿名函数表达式

b.return一个变量,其中这个变量里包含你要暴露的东西

c.返回的这个变量将赋值给window

window(或者是任意一个全局对象)作为一个带有多个属性的全局对象,也可以把window当成一个参数,以对象的方式,在其它函数中实现调用。用下面的例子说明:

(function($, YAHOO) {//这里,我们的代码就可以使用全局的jQuery对象了,YAHOO也是一样

$.aa = function(){//code

}

} (jQuery, YAHOO));//调用 jQuery.aa();

下面是一个标准的Module模式,通过匿名函数的返回值来返回这个全局变量:

var blogModule = (function() {var my = {}, privateName = "博客园";functionprivateAddTopic(data) {//这里是内部处理代码

}

my.Name=privateName;

my.AddTopic= function(data) {

privateAddTopic(data);

};returnmy;

} ());//调用 blogModule.my();

在一些大型项目里,将一个功能分离成多个文件是非常重要的,因为可以多人合作易于开发。再回头看看上面的全局参数导入例子,我们能否把blogModule自身传进去呢?答案是肯定的,我们先将blogModule传进去,添加一个函数属性,然后再返回就达到了我们所说的目的:

var blogModule = (function(my) {

my.AddPhoto= function() {//添加内部代码

};returnmy;

} (blogModule||{}));

(function(my){

my.AddPhoto= function() {//添加内部代码

};returnmy;

})(blogModule||{}));//调用 blogModule.AddPhoto();

那么,多个自执行函数间是怎么调用的呢?

(function(owner) {//第一个匿名闭包

owner.debug = true;//Ajax相关参数配置

owner.ajax ={

timeout:10000,

type:'post',

dataType:'json',

};

})(window.C= {}));

如果第二个函数想调用 全局变量为C中的 对象呢?要怎么写?

(function($, owner) {//这里调用上面全局变量为C 中的对象呢

if(!C.debug) return false;var url = 'aaa.html';

mui.ajax({

url: url,

dataType: C.ajax.dataType,

type: C.ajax.type,

});

})(mui, window.app= {});

再举个例子,同样的,不同自执行闭包函数间的调用方法:

(function($, owner) {//获取语言闭包

owner.getLanguage = function() {var language =localStorage.getItem(C.state.field.language);if(typeof language == "undefined" || language === null || language == '') {var currentLang =navigator.language;if(!currentLang)

currentLang=navigator.browserLanguage;

language=currentLang.toLowerCase();

language= language.replace(/-/g, '_');if(language != 'en_us' && language != 'zh_cn')

language= 'en_us';

localStorage.setItem(C.state.field.language, language);

}

//在上面的解析中有说过,Module模式,return 一个变量,这个变量就是要爆露的东西。通过这个函数的全局变量,这个 language 可以在任何地方调用//return一个变量,其中这个变量里包含你要暴露的东西//全局调用 storage.language

returnlanguage;

};

})(mui, window.storage={}));

(function($, owner) {

owner.language={};

owner.preload= function(settings){var defaults ={

name:'i18n',

language:'',

path:'/',

cache:true,

encoding:'UTF-8',

autoReplace:true,

success:null,

error:null,

};

settings=$.extend(defaults, settings);if(settings.language === null || settings.language == '') {//全局调用 storage.language

settings.language =storage.getLanguage();

}

}

})(mui, window.i18n= {});

所以 匿名闭包的调用规则是这样的,立即执行(最后一个括号) (window),如果把window作为一个参数进行传递,那么就把它以对象的方式,在其它函数中实现全局调用。

如果有错误,请大家指正,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问题研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值