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

技术文章 6个月前 完美者
1,434 0

标签:全局对象   turn   func   attr   函数   var   注册   port   支持   

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

(function(window,undefined ){
//
})();
这是一个自调用匿名函数。什么东东呢?在第一个括号内,创建一个匿名函数;第二个括号,立即执行

为什么要创建这样一个“自调用匿名函数”呢?
通过定义一个匿名函数,创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏全局的命名空间。这点非常有用也是一个JS框架必须支持的功能,jQuery被应用在成千上万的JavaScript程序中,必须确保jQuery创建的变量不能和导入他的程序所使用的变量发生冲突。
接下来看看在 自调用匿名函数 中都实现了什么功能,按照代码顺序排列:

复制代码
复制代码
(function( window, undefined ) {
// 构造jQuery对象
var jQuery = function( selector, context ) {
return new jQuery.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

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

标签:全局对象   turn   func   attr   函数   var   注册   port   支持   

原文地址:https://www.cnblogs.com/fengw125/p/13939636.html

版权声明:完美者 发表于 2020-11-07 17:03:57。
转载请注明:自调用匿名函数(匿名闭包)解析与调用 | 完美导航

暂无评论

暂无评论...