0

0

jQuery自调用匿名函数是如何调用的?

不言

不言

发布时间:2018-08-01 16:04:16

|

3970人浏览过

|

来源于php中文网

原创

这篇文章给大家介绍的内容是关于jquery自调用匿名函数是如何调用的?有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

打开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 );

为什么要传入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(){})();

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

淘源码商城PHP淘宝查信誉
淘源码商城PHP淘宝查信誉

淘宝上现在有在卖的版本,大部分查询是调用其他站的,账户具体点数查询错误,其他查询,如排名等都是调用其他站的,调用站没问题,那么就没问题

下载

1、要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明;
2、立即执行函数可以当作是一个私有作用域,作用域内部可以访问外部的变量,而外部环境是不能访问作用域内部的变量的,因此,立即执行函数是一个封闭的作用域,不会和外部作用域起冲突。
  JQuery使用的就是这种方法,将JQuery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用JQuery代码时,可以达到保护JQuery内部变量的作用。
3、Module模式,是自执行函数的高级模式,可以非常方便的在各个匿名闭包中以全局对象调用闭包函数。                 

Module 模式为:
  a.创建一个立即调用的匿名函数表达式
  b.return一个变量,其中这个变量里包含你要暴露的东西
  c.返回的这个变量将赋值给window

(function () {
var i = 0;
return {
    get: function () {
        return i;
    },
    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模式
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 = "博客园";

function privateAddTopic(data) {
    // 这里是内部处理代码
}

my.Name = privateName;
my.AddTopic = function (data) {
    privateAddTopic(data);
};

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

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

var blogModule = (function (my) {
my.AddPhoto = function () {
    //添加内部代码  
};
return my;
} (blogModule || {}));


(function (my){
my.AddPhoto = function () {
    //添加内部代码  
};
return my;
})(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                                  
    return language;
};
})(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作为一个参数进行传递,那么就把它以对象的方式,在其它函数中实现全局调用。

相关推荐:

js实现模态窗口增加与删除案例分享(纯代码)

js对象类型怎么判断?详解js里的基本类型转换

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
jquery插件有哪些
jquery插件有哪些

jquery插件有jQuery UI、jQuery Validate、jQuery DataTables、jQuery Slick、jQuery LazyLoad、jQuery Countdown、jQuery Lightbox、jQuery FullCalendar、jQuery Chosen和jQuery EasyUI等。本专题为大家提供jquery插件相关的文章、下载、课程内容,供大家免费下载体验。

151

2023.09.12

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

312

2023.10.13

jquery删除元素的方法
jquery删除元素的方法

jquery可以通过.remove() 方法、 .detach() 方法、.empty() 方法、.unwrap() 方法、.replaceWith() 方法、.html('') 方法和.hide() 方法来删除元素。更多关于jquery相关的问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

396

2023.11.10

jQuery hover()方法的使用
jQuery hover()方法的使用

hover()是jQuery中一个常用的方法,它用于绑定两个事件处理函数,这两个函数将在鼠标指针进入和离开匹配的元素时执行。想了解更多hover()的相关内容,可以阅读本专题下面的文章。

504

2023.12.04

jquery实现分页方法
jquery实现分页方法

在jQuery中实现分页可以使用插件或者自定义实现。想了解更多jquery分页的相关内容,可以阅读本专题下面的文章。

187

2023.12.06

jquery中隐藏元素是什么
jquery中隐藏元素是什么

jquery中隐藏元素是非常重要的一个概念,在使用jquery隐藏元素之前,需要先了解css样式中关于元素隐藏的属性,比如display、visibility、opacity等属性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

120

2024.02.23

jquery中什么是高亮显示
jquery中什么是高亮显示

jquery中高亮显示是指对页面搜索关键词时进行高亮显示,其实现办法:1、先获取要高亮显示的行,获取搜索的内容,再遍历整行内容,最后添加高亮颜色;2、使用“jquery highlight”高亮插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

176

2024.02.23

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

40

2026.01.13

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号