Maison  >  Article  >  interface Web  >  Comment jQuery appelle-t-il sa fonction anonyme auto-appelante ?

Comment jQuery appelle-t-il sa fonction anonyme auto-appelante ?

不言
不言original
2018-08-01 16:04:163728parcourir

Cet article vous présente comment jQuery appelle les fonctions anonymes auto-appelantes ? Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

Ouvrez le code source de jQuery. Vous verrez d'abord cette structure de code :

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

Il s'agit d'une fonction anonyme à appel automatique. Quels trucs ? Dans la première parenthèse, créez une fonction anonyme ; dans la deuxième parenthèse, exécutez-la immédiatement

Pourquoi créer une telle « fonction anonyme auto-appelante » ?
En définissant une fonction anonyme, un espace de noms "privé" est créé. Les variables et méthodes de cet espace de noms ne détruiront pas l'espace de noms global. C'est très utile et c'est une fonctionnalité qu'un framework JS doit prendre en charge. jQuery est utilisé dans des milliers de programmes JavaScript. Il faut s'assurer que les variables créées par jQuery ne peuvent pas entrer en conflit avec les variables utilisées par le programme qui l'importe.
Ensuite, examinons quelles fonctions sont implémentées dans les fonctions anonymes auto-appelantes, classées dans l'ordre du code :

(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);

Les fonctions anonymes sont appelées littéraux de fonction syntaxiquement. La syntaxe JavaScript doit entourer les fonctions anonymes. . Entre parenthèses, en fait, il existe deux manières d'écrire des fonctions anonymes auto-appelantes :

(function() {
console.info( this );
console.info( arguments );
}( window ) );
(function() {
console.info( this );
console.info( arguments );
})( window );

Pourquoi devez-vous passer dans window ?

En passant la variable window, la fenêtre passe d'une variable globale à une variable locale. Lors de l'accès à la fenêtre dans le bloc de code jQuery, il n'est pas nécessaire de restaurer la chaîne de portée au niveau supérieur. scope, ce qui peut être plus rapide. Accédez à la fenêtre ; ce n'est pas la clé. Plus important encore, passer la fenêtre en paramètre peut être optimisé lors de la compression du code. Jetez un œil à jquery-1.6.1.min.js : (fonction. (a,b){} )(window); // la fenêtre est optimisée pour être un
Grâce à l'introduction ci-dessus, nous comprenons à peu près que () peut exécuter une expression de fonction immédiatement.

La fonction anonyme sert de "conteneur". L'intérieur du "conteneur" peut accéder aux variables externes, mais l'environnement externe ne peut pas accéder aux variables à l'intérieur du "conteneur".
Donc ( function(){. ...} )() Les variables définies en interne n'entreront pas en conflit avec les variables externes, communément appelées « wrappers anonymes » ou « espaces de noms ».

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

Identique à ci-dessous
(function () {/ code interne/})();

En termes simples, () est utilisé pour find la valeur, donc this () ne peut à aucun moment être vide car il doit être calculé. L'analyse des fonctions n'analysera que {}, pas ().

Mettre une expression dans () renverra la valeur de l'expression ;
Mettre une fonction dans () renverra la fonction elle-même (function(){}());
If ( ) qui suit immédiatement la fonction signifie que la fonction est appelée, c'est-à-dire que la fonction est évaluée : (function(){})();

(function() {
//自执行函数中的内部变量,外部是无法访问的
var name = 'kevin';
})( window );

name //indéfini, la valeur de name ne peut pas être obtenu

Lorsque le code sera exécuté, il donnera la priorité à l'analyse de la [fonction déjà déclarée]

                                                                                                  utiliser   utiliser utiliser utiliser                              ‐      ‐ ‐ ‐‐‐'‐'‐ � � � � � Il est écrit séparément, son exécution nécessite donc l'appel d'autres fonctions. Les fonctions anonymes habituellement vues sont passées en paramètres. La fonction d'exécution immédiate elle-même est une fonction anonyme,
        L'ordre d'exécution du code js :                                                                                                                                                                                 //Expression de fonction var test = fonction (){}
                                                                     //                                                                                                                //  , il y a quelques points à comprendre :

1. Si vous souhaitez ajouter des parenthèses après le corps de la fonction pour l'appeler immédiatement, la fonction doit être une expression de fonction, pas une déclaration de fonction
2. Exécutez la fonction immédiatement. scope. Les variables externes sont accessibles à l'intérieur de la portée, mais l'environnement externe ne peut pas accéder aux variables à l'intérieur de la portée. Par conséquent, la fonction d'exécution immédiate est une portée fermée et n'interagira pas avec le conflit externe.
JQuery utilise cette méthode, en encapsulant le code JQuery dans (function (window, undefined){...jquery code...} (window), lors de l'appel du code JQuery dans la portée globale, vous pouvez protéger les variables internes de JQuery

3. Le mode module est un mode avancé de fonctions auto-exécutables. Il est très pratique d'appeler des fonctions de fermeture en tant qu'objets globaux dans chaque fermeture anonyme.

Le mode module est :
a. . Créez une expression de fonction anonyme qui est appelée immédiatement
b. Renvoyez une variable qui contient l'élément que vous souhaitez exposer
c. La variable renvoyée sera affectée à window

<.>/


Ce qui précède est l'analyse des fonctions anonymes auto-appelantes, alors comment une telle fonction est-elle appelée

(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只存在于闭包)

*//Ce qui suit concerne l'appel de variables globales, c'est-à-dire l'appel de la fonction de fermeture anonyme*
/Sortez à nouveau du mode ModuleMode Module, c'est-à-dire la création et l'appel de fermetures anonymes :

   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里的基本类型转换

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn