Maison  >  Article  >  interface Web  >  Détails sur le développement de votre propre framework JQuery

Détails sur le développement de votre propre framework JQuery

黄舟
黄舟original
2017-03-01 14:52:201138parcourir

Encapsulation via des objets json

C'est la méthode d'encapsulation la plus simple, comme suit :

<script type="text/javascript">
    /**
    *自执行的匿名函数,可以实现链式调用
    **/
    (function(w){
        var DQuery={            
        &#39;name&#39;:&#39;DQuery&#39;,            
        &#39;version&#39;:&#39;2016-06-05&#39;,            
        &#39;getVersion&#39;:function(){
                console.log(this.version);                
                return this;
            },
            getName:function(){
                console.log(this.name);                
                return this;
            },
            showinfo:function(){
                this.getVersion();                
                this.getName();                
                return this;
            }
        };

        window.DQuery=$$=DQuery; //让外边可以调用
    }(window));    </script>

Avantages, simplicité, très facile à lire.
Inconvénients : DQuery est un objet, pas un constructeur. Lorsque DQuery est généré, toutes les informations qu'il contient sont exposées (comme indiqué ci-dessous). Deuxièmement, il ne peut pas être personnalisé en conséquence pour générer différents objets adaptés à une utilisation dans différentes situations.
Détails sur le développement de votre propre framework JQuery

Encapsulation via constructeur

Version 1

Cette version est la première version à laquelle tout le monde pensera. Le programme est le suivant :

(function(w){
        var DQuery=function(){
            this.alias=null;
        }
        DQuery.prototype ={            &#39;name&#39;:&#39;DQuery&#39;,            &#39;version&#39;:&#39;2016-06-05&#39;,            &#39;setAlias&#39;:function(alias){
                this.alias=alias;                return this;
            },            &#39;getAlias&#39;:function(alias){
                console.log(this.alias);                return this;
            },            &#39;getVersion&#39;:function(){
                console.log(this.version);                return this;
            },
            getName:function(){
                console.log(this.name);                return this;
            },
            showinfo:function(){
                this.getVersion();                this.getName();                return this;
            }
        }

        window.DQuery=$$=DQuery; //让外边可以调用
    }(window));

Le code d'appel est le suivant

    var p1= new DQuery();
    p1.alias=&#39;p1&#39;
    var p2= new $$();
    p2.alias=&#39;p2&#39;
    console.log(p1);    console.log(p2);    
    console.log(p1.showinfo==p2.showinfo);    console.log(typeof(DQuery));

L'effet est le suivant
Détails sur le développement de votre propre framework JQuery
Avantages : Comme le montre la sortie, tout d'abord, DQuery est un constructeur qui nous permet de générer différentes données en fonction de l'objet paramètres correspondant. Deuxièmement, les variables et fonctions définies dans le prototype de DQuery sont communes à tous les objets et sont équivalentes aux statiques.
Inconvénients : Il est un peu gênant de devoir créer un nouveau DQuery à chaque fois que vous créez un objet. Deuxièmement, c’est quand même un peu révélateur.

Version 2

Dans la version 1, chaque fois qu'un objet est créé, un nouveau doit être créé. Peut-être que notre première pensée est de le changer comme suit :

var DQuery=function(){
            this.alias=null;            return  new DQuery();
        }

De cette façon, du point de vue du code, le problème existant est résolu, mais un nouveau problème apparaît. Autrement dit, étant donné que créer son propre objet dans DQuery équivaut à un appel récursif, un problème de boucle infinie se produit.
Détails sur le développement de votre propre framework JQuery

Version 3

Pour résoudre les problèmes des versions 1 et 2, les améliorations suivantes peuvent être apportées

(function(w){
        var DQuery=function(alias){
            this.alias=alias;            return new DQuery.prototype.init();
        }
        DQuery.prototype ={            &#39;name&#39;:&#39;DQuery&#39;,            &#39;version&#39;:&#39;2016-06-05&#39;,            &#39;init&#39;:function(){

            },            &#39;setAlias&#39;:function(alias){
                this.alias=alias;                return this;
            },            &#39;getAlias&#39;:function(alias){
                return this;
            },            &#39;getVersion&#39;:function(){
                return this.version;
            },
            getName:function(){
                return this.name;
            },
            showinfo:function(){
                return this.name+&#39;:&#39;+this.version;
            }
        }

        window.DQuery=$$=DQuery; //让外边可以调用
    }(window));

    console.log(typeof($$));//$$是一个构造函数
    console.log(typeof($$()));//$$()返回一个对象
    console.log(typeof(new $$()));//new $$()返回一个对象

    var p1=$$(&#39;id1&#39;);	var p2=new $$(&#39;id2&#39;);

Avantages : Résoudre les problèmes dans les versions 1 et 2 Problèmes dans la version 2.
Inconvénients : Les propriétés et méthodes de la classe (dans le constructeur) ne peuvent pas être appelées.

Version 4

Pour les objets créés par new, la portée dans l'objet est la portée de la fonction, et son prototype est également le prototype du constructeur (pour plus de détails, veuillez vous référer au contenu supplémentaire), alors, puisque nous utilisons new DQuery.prototype.init();, le prototype de l'objet renvoyé est égal au prototype de la fonction init. Mais nous voulons qu'il pointe vers le prototype de la fonction DQuery. A ce stade, il existe deux approches :
Option 1 : Dans la méthode init, on renvoie ce pointant vers l'objet DQuery, mais c'est difficile à faire dans ces conditions, car je suis sûr que l'utilisateur crée l'objet via new DQuery Ou appelez DQuery() directement pour créer l'objet
Option 2 : Nous pouvons définir init.prototype=DQuery.prototype, de sorte que bien que l'objet soit créé à l'aide du constructeur init, le prototype de l'objet soit le même que celui de DQuery.
Après avoir amélioré la version 3, le code est le suivant :

(function(w){
        var DQuery=function(alias){
            this.alias=alias;            
            return new DQuery.prototype.init();
        }
        DQuery.prototype ={            
        &#39;self&#39;:this,            
        &#39;name&#39;:&#39;DQuery&#39;,            
        &#39;version&#39;:&#39;2016-06-05&#39;,            
        &#39;init&#39;:function(){

            },            &#39;setAlias&#39;:function(alias){
                this.alias=alias;                return this;
            },            &#39;getAlias&#39;:function(alias){
                return this;
            },            &#39;getVersion&#39;:function(){
                return this.version;
            },
            getName:function(){
                return this.name;
            },
            showinfo:function(){
                return this.name+&#39;:&#39;+this.version;
            }
        }
        DQuery.prototype.init.prototype=DQuery.prototype;
        window.DQuery=$$=DQuery; //让外边可以调用
    }(window));

    console.log(typeof($$));//$$是一个构造函数
    console.log(typeof($$()));//$$()返回一个对象
    console.log(typeof(new $$()));//new $$()返回一个对象
    var p1=new DQuery();
    console.log(p1);
    console.log(p1 instanceof DQuery); //true

Détails sur le développement de votre propre framework JQuery
On constate qu'à ce stade, il répond pleinement à nos exigences et résout le problème ci-dessus. .

Version 5

Au début je pensais qu'il n'y avait pas de problème avec la version 4, mais finalement j'ai trouvé que la version 4 avait encore un petit problème, c'est-à-dire que l'objet renvoyé ne pouvait pas accéder aux propriétés défini par le constructeur DQuery. Pour résoudre ce problème, nous pouvons le résoudre en appelant ou en postulant. Bien sûr, ce n'est en fait pas nécessaire, car nous pouvons définir directement certaines propriétés dans la méthode init. Pourquoi les définir dans DQuery et ensuite nous causer des problèmes.
****Les versions suivantes continueront à s'ajouter********** *** **

Résumé

Le schéma de relation approximatif est le suivant
Détails sur le développement de votre propre framework JQuery
Le code simplifié est le suivant :

(function(w){
        var DQuery=function(){
            return new DQuery.prototype.init();
        }
        DQuery.prototype ={            //定义一些静态变量
            &#39;self&#39;:this,            &#39;name&#39;:&#39;DQuery&#39;,            &#39;version&#39;:&#39;2016-06-05&#39;,            // 构造函数方法
            &#39;init&#39;:function(){
                //定义一些变量属性
            },            //定义一些方法
            &#39;setAlias&#39;:function(alias){
                this.alias=alias;                return this;
            }           
        }
        DQuery.prototype.init.prototype=DQuery.prototype;
        window.DQuery=$$=DQuery; //让外边可以调用
    }(window));

Supplément

L'impact de la valeur de retour du constructeur sur le nouvel objet

Tout d'abord, résumons le processus de création d'un nouvel objet. Par exemple, en utilisant le constructeur Student pour créer un objet var s1=new Student(), le processus peut être résumé comme suit : créez d'abord un nouvel objet, et deuxièmement attribuez la portée du constructeur au nouvel objet (cela pointe donc vers le nouvel objet, et Student.prototype est affecté au prototype d'objet), puis attribuez l'objet à s1.

Aucune valeur de retour n'est spécifiée dans le constructeur

Dans ce cas, une nouvelle instance d'objet sera renvoyée par défaut.

Il existe une valeur de retour spécifiée dans le constructeur

1 Si la valeur de retour est un type de données de base, une nouvelle instance d'objet sera toujours renvoyée.
2. Si la valeur de retour est un objet, l'objet renvoyé devient la valeur d'objet spécifiée. Dans ce cas, l'objet référencé par cette valeur est ignoré.
3. Si vous renvoyez une fonction, new ne renverra pas un objet, mais la fonction.

//无返回值
    function Student1(){
        this.name=&#39;dqs&#39;;
    }    var p1=new Student1();
    console.log(typeof(p1));//object
    console.log(&#39;name&#39; in p1 ); //true
    console.log(p1 instanceof Student1 ); //true

    //返回function
    function Student2(){
        this.name=&#39;dqs&#39;;        return function(){};
    }    var p2=new Student2();

    console.log(typeof(p2));//function
    console.log(p2 instanceof Student2 ); //false
    //返回基本类型

    //返回基本类型
    function Student3(){
        this.name=&#39;dqs&#39;;        return &#39;nihao&#39;;
    }    var p3=new Student3();
    console.log(typeof(p3));//object
    console.log(&#39;name&#39; in p3 ); //true
    console.log(p3 instanceof Student3 ); //true

    //返回对象类型
    function Student4(){
        this.name=&#39;dqs&#39;;        return {&#39;location&#39;:&#39;hsd&#39;};
    }    var p4=new Student4();
    console.log(typeof(p4));//object
    console.log(&#39;name&#39; in p4 ); //false
    console.log(p3 instanceof Student4 ); //false


Ce qui précède concerne les détails du développement de votre propre framework JQuery. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn). !

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