これは、次のような最も単純なカプセル化方法です:
<script type="text/javascript"> /** *自执行的匿名函数,可以实现链式调用 **/ (function(w){ var DQuery={ 'name':'DQuery', 'version':'2016-06-05', 'getVersion':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>
利点、シンプルで読みやすい。
欠点: DQuery はコンストラクターではなくオブジェクトです。DQuery が出力されると、それに含まれるすべての情報が公開されます (以下に示すように)。第 2 に、さまざまな状況での使用に合わせてさまざまなオブジェクトを生成するようにカスタマイズすることができません。
このバージョンは誰もが最初に考えるバージョンです: プログラムは次のとおりです:
(function(w){ var DQuery=function(){ this.alias=null; } DQuery.prototype ={ 'name':'DQuery', 'version':'2016-06-05', 'setAlias':function(alias){ this.alias=alias; return this; }, 'getAlias':function(alias){ console.log(this.alias); return this; }, 'getVersion':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));
呼び出しコードは次のとおりです
var p1= new DQuery(); p1.alias='p1' var p2= new $$(); p2.alias='p2' console.log(p1); console.log(p2); console.log(p1.showinfo==p2.showinfo); console.log(typeof(DQuery));
効果は次のとおりです。
利点: 出力からわかります。まず第一に、DQuery は、対応するパラメーターに基づいてさまざまなオブジェクトを生成できるコンストラクターです。次に、DQuery のプロトタイプで定義された変数と関数はすべてのオブジェクトに共通であり、静的と同等です。
欠点: オブジェクトを作成するたびに新しい DQuery を作成する必要があるのは少し面倒です。第二に、まだ少し明らかになっていることです。
バージョン 1 では、オブジェクトが作成されるたびに、新しいオブジェクトを作成する必要があります。おそらく、最初に考えられるのは、次のように変更することです:
var DQuery=function(){ this.alias=null; return new DQuery(); }
このように、既存の問題は次のとおりです。コードの観点からは解決されましたが、新たな問題が発生しました。つまり、DQuery で独自のオブジェクトを作成することは再帰呼び出しと同等であるため、無限ループの問題が発生します。
バージョン1と2の問題に対応して、次の改善を行うことができます
(function(w){ var DQuery=function(alias){ this.alias=alias; return new DQuery.prototype.init(); } DQuery.prototype ={ 'name':'DQuery', 'version':'2016-06-05', 'init':function(){ }, 'setAlias':function(alias){ this.alias=alias; return this; }, 'getAlias':function(alias){ return this; }, 'getVersion':function(){ return this.version; }, getName:function(){ return this.name; }, showinfo:function(){ return this.name+':'+this.version; } } window.DQuery=$$=DQuery; //让外边可以调用 }(window)); console.log(typeof($$));//$$是一个构造函数 console.log(typeof($$()));//$$()返回一个对象 console.log(typeof(new $$()));//new $$()返回一个对象 var p1=$$('id1'); var p2=new $$('id2');
利点:バージョン1と2の問題を解決しました。
欠点: クラス (コンストラクター内) のプロパティとメソッドを呼び出すことができません。
newで作成したオブジェクトの場合、オブジェクト内のスコープは関数のスコープであり、そのプロトタイプはコンストラクターのプロトタイプでもあります(詳細は補足内容を参照してください)。 new DQuery.prototype.init();
を使用すると、返されるオブジェクトのプロトタイプは init 関数のプロトタイプと同じになります。ただし、DQuery 関数のプロトタイプを指すようにしたいのです。この時点で、2 つのアプローチがあります: new DQuery.prototype.init();
,返回对象的prototype等于init函数的prototype。但是我们希望其指向DQuery函数的prototype。此时,有两种做法:
方案一:我们在init方法中,返回指向DQuery对象的this,但是这个在该条件下很难做的,因为我确定,用户是通过new DQuery来创建对象还是直接调DQuery()来创建对象
方案二:我们可以让init.prototype=DQuery.prototype,这样虽然是用init构造函数创建的对象,但是对象的prototype和DQuery的prototype相同。
于是将版本三改进后,代码如下如下:
(function(w){ var DQuery=function(alias){ this.alias=alias; return new DQuery.prototype.init(); } DQuery.prototype ={ 'self':this, 'name':'DQuery', 'version':'2016-06-05', 'init':function(){ }, 'setAlias':function(alias){ this.alias=alias; return this; }, 'getAlias':function(alias){ return this; }, 'getVersion':function(){ return this.version; }, getName:function(){ return this.name; }, showinfo:function(){ return this.name+':'+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
可以发现,此时已经有了完全符合我们的要求了,也解决了上面出现的问题。
开始以为版本4是没有什么问题,最后发现原来版本4还是有个小问题,即返回的对象,没法访问DQuery构造函数定义的属性。针对这个问题,我们可以通过call或者apply来解决。当然,其实也没必要,因为我们,直接可以讲一些属性定义在init方法中,何必定义在DQuery,然后给自己找麻烦呢。
****后续版本会继续添加*************
大致关系图如下
代码简化后如下:
(function(w){ var DQuery=function(){ return new DQuery.prototype.init(); } DQuery.prototype ={ //定义一些静态变量 'self':this, 'name':'DQuery', 'version':'2016-06-05', // 构造函数方法 'init':function(){ //定义一些变量属性 }, //定义一些方法 'setAlias':function(alias){ this.alias=alias; return this; } } DQuery.prototype.init.prototype=DQuery.prototype; window.DQuery=$$=DQuery; //让外边可以调用 }(window));
首先我们来总结一下new一个对象的过程。比如使用Student构造函数创建对象var s1=new Student()
オプション 1: init メソッドで、DQuery オブジェクトを指す this を返しますが、ユーザーが新しい DQuery を通じてオブジェクトを作成したかどうかが確実であるため、この条件下でこれを行うのは困難です。または直接 DQuery() を呼び出してオブジェクトを作成します
//无返回值 function Student1(){ this.name='dqs'; } var p1=new Student1(); console.log(typeof(p1));//object console.log('name' in p1 ); //true console.log(p1 instanceof Student1 ); //true //返回function function Student2(){ this.name='dqs'; return function(){}; } var p2=new Student2(); console.log(typeof(p2));//function console.log(p2 instanceof Student2 ); //false //返回基本类型 //返回基本类型 function Student3(){ this.name='dqs'; return 'nihao'; } var p3=new Student3(); console.log(typeof(p3));//object console.log('name' in p3 ); //true console.log(p3 instanceof Student3 ); //true //返回对象类型 function Student4(){ this.name='dqs'; return {'location':'hsd'}; } var p4=new Student4(); console.log(typeof(p4));//object console.log('name' in p4 ); //false console.log(p3 instanceof Student4 ); //false
」を書いてください。
これが私たちの要件を完全に満たしており、上記の問題を解決していることがわかります。 バージョン 5
当初、バージョン 4 には問題がないと考えていましたが、最終的にバージョン 4 にはまだ小さな問題があることがわかりました。つまり、返されたオブジェクトは DQuery コンストラクターによって定義されたプロパティにアクセスできませんでした。この問題を解決するには、電話や申し込みをすることで解決できます。もちろん、一部のプロパティを init メソッドで直接定義できるため、実際には必要ありません。DQuery で定義すると、問題が発生します。
****以降のバージョンでは、********* が引き続き追加されます。 *** ***
概要
コードは次のように簡略化されています:
var s1=new Student()
を作成します。このプロセスは次のように要約できます。最初に新しいオブジェクトを作成し、次にコンストラクターのスコープをオブジェクトに割り当てます。新しいオブジェクト (つまり、this はこの新しいオブジェクトを指し、Student.prototype はオブジェクトのプロトタイプに割り当てられます)、そのオブジェクトを s1 に割り当てます。 🎜🎜コンストラクターには戻り値の指定はありません🎜🎜この場合、デフォルトでは新しいオブジェクトインスタンスが返されます。 🎜🎜コンストラクター🎜🎜1に指定された戻り値がある場合、戻り値が基本データ型の場合でも、新しいオブジェクトのインスタンスが返されます。 🎜2.. 戻り値がオブジェクトの場合、返されるオブジェクトは指定されたオブジェクト値になります。この場合、この値によって参照されるオブジェクトは破棄されます。 🎜3. 関数を返す場合、new はオブジェクトではなく関数を返します。 🎜rrreee🎜🎜🎜🎜 上記は、独自の JQuery フレームワークの開発の詳細です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。 🎜🎜