ホームページ > 記事 > ウェブフロントエンド > JS の一般的なデザイン パターン
大規模なシングルページアプリケーションでは、複雑さが一定レベルに達すると、デカップリングに適した設計パターンがなく、その後の開発の開始が困難になります。
デザインパターンはまさにデカップリングのために存在します。
シングルトン パターンの中核は、インスタンスが 1 つだけ存在することを保証し、グローバル アクセスを提供することです。
「単一責任の原則」を満たす: プロキシモードを使用すると、シングルトンが作成されたかどうかはコンストラクターで判断されません
遅延の原則を満たす
はログインウィンドウをポップアップします。 。
var getSingle = function (fn) { var res; return function() { return res || (res = fn.apply(this, arguments)); } } var createPopup() { var p = document.createElement('p'); p.innerHTML = "Login window"; p.style.display = "none"; document.body.appendChild(p); return p; } var createLoginPopup = getSingle(createPopup); //create popup p here by using a given function, 满足两个原则 document.getElementById("loginBt").onclick = function() { var popup = createLoginPopup(); pop.style.display = "block"; }
/** * 构造一个动物的函数 */ function Animal(name, color){ this.name = name; this.color = color; this.getName = function(){ return this.name; } } // 实例一个对象 var cat = new Animal('猫', '白色'); console.log( cat.getName() );
function Person(){ } Person.prototype.name = "bill"; Person.prototype.address = "GuangZhou"; Person.sayName = function (){ alert(this.name); } var person1 = new Person(); var person2 = new Person(); //测试代码 alert(person1.name); // bill alert(person2.name); // bill person1.sayName(); //bill person2.sayName(); //bill person1.name = "666"; alert(person1.name); // 666 alert(person2.name); // bill person1.sayName(); //666 person2.sayName(); //bill
/** * 混合模式 = 原型模式 + 构造函数模式 */ function Animal(name, color){ this.name = name; this.color = color; console.log( this.name + this.color) } Animal.prototype.getInfo = function(){ console.log('名称:'+ this.name); } function largeCat(name, color){ Animal.call(null, name, color); this.color = color; } largeCat.prototype = create(Animal.prototype); function create (parentObj){ function F(){} F.prototype = parentObj; return new F(); }; largeCat.prototype.getColor = function(){ return this.color; } var cat = new largeCat("Persian", "白色"); console.log( cat )
ファクトリー: b オブジェクトは関数によって内部的に生成され、返されます。
1. function a(name){ var b = new object(); b.name = name; b.say = function(){ alert(this.name); } return b } 2. function Animal(opts){ var obj = new Object(); obj.name = opts.name; obj.color = opts.color; obj.getInfo = function(){ return '名称:'+obj.name +', 颜色:'+ obj.color; } return obj; } var cat = Animal({name: '波斯猫', color: '白色'}); cat.getInfo();
シンプルなファクトリ パターンの考え方は、オブジェクトを作成し、さまざまなクラスをインスタンス化するだけで済みます。その後、このオブジェクトに対して多数のメソッドとプロパティを使用し、最後に戻り値を返します。オブジェクト
//basketball base class var Baseketball = function(){ this.intro = 'baseketball is hotting at unitedstates'; } Baseketball.prototype = { getMember : function(){\ console.log('each team needs five players'); }, getBallSize : function(){ console.log('basketball is big'); } } //football base class var Football = function(){ this.intro = 'football is popular at all of the world'; } Football = function(){ getMember = function(){ }, getBallSize = function(){ } } //sport factory var SportsFactory = function(name){ switch(name){ case 'NBA': return new Baseketball(); case 'wordCup': return new Football(); } } //when you want football var football = SportsFactory('wordCup'); console.log(football); console.log(football.intro); football.getMember();
デコレータパターン
相互に交換可能なアルゴリズムを定義し、それらをカプセル化します。
オープンクローズ原則に従う: 使用するアルゴリズムを変更する場合、関数を深く変更する必要はなく、ストラテジー クラスを変更するだけで済みます。
大きく分けて戦略型と環境型の2つに分かれます。戦略クラスはさまざまなアルゴリズムをカプセル化するために使用され、特定の計算プロセスを担当します。環境クラスはユーザーのリクエストを受信し、そのリクエストを特定の戦略クラスに委託します。各戦略クラスで実装されるアルゴリズムや計算結果は異なりますが、環境クラスによる戦略クラスの呼び出し方法は同じであるため、これはポリモーフィズムを反映しています。さまざまなアルゴリズムを実装するには、環境クラスの戦略クラスを置き換えるだけで済みます。
js では、ストラテジー クラスを構築する必要はなく、関数をストラテジー オブジェクトとして直接使用できます。
例
var strategies = { "s1": function() { //algo 1 }, "s2": function() { //algo 2 }, "s3": function() { //algo 3 } } var someContext = new SomeConext(); someContext.start("s1"); //using s1 to calculate //someContext.add("s1"); or add s1 as a rule for validation
外観モード
関数
function a(x){ // do something } function b(y){ // do something } function ab( x, y ){ a(x); b(y); }
次の例では、ブロックを配置します。外観ロールへのデフォルトイベントのバブリングとブロック:
var N = window.N || {}; N.tools = { stopPropagation : function( e ){ if( e.stopPropagation ){ e.stopPropagation(); }else{ e.cancelBubble = true; } }, preventDefault : function( e ){ if( e.preventDefault ){ e.preventDefault(); }else{ e.returnValue = false; } }, stopEvent : function( e ){ N.tools.stopPropagation( e ); N.tools.preventDefault( e ); }
JavaScript での外観モードの適用は、主に 2 つのカテゴリに分類できます。たとえば、関数 a の呼び出しは、基本的に関数を呼び出す前に繰り返し表示されます。 b、構造を最適化するために、このコード部分を外観ロールでラップすることを検討できます。もう 1 つの方法は、一部のブラウザと互換性のない API を外観内に配置して判断することです。これらの問題に対処する最善の方法は、ブラウザ間の違いをすべて外観モード インスタンスに集中させて外部インターフェイスを提供することです。
プロキシ パターン
仮想プロキシ
画像の遅延読み込み
//图片加载 let imageEle = (function(){ let node = document.createElement('img'); document.body.appendChild(node); return { setSrc:function(src){ node.src = src; } } })(); //代理对象 let proxy = (function(){ let img = new Image(); img.onload = function(){ imageEle.setSrc(this.src); }; return { setSrc:function(src){ img.src = src; imageEle.setSrc('loading.gif'); } } })(); proxy.setSrc('example.png');
//上传请求 let upload = function(ids){ $.ajax({ data: { id:ids } }) } //代理合并请求 let proxy = (function(){ let cache = [], timer = null; return function(id){ cache[cache.length] = id; if(timer) return false; timer = setTimeout(function(){ upload(cache.join(',')); clearTimeout(timer); timer = null; cache = []; },2000); } })(); // 绑定点击事件 let checkbox = document.getElementsByTagName( "input" ); for(var i= 0, c; c = checkbox[i++];){ c.onclick = function(){ if(this.checked === true){ proxy(this.id); } } }
メリットとデメリット
//计算乘积 let mult = function(){ let result = 1; for(let i = 0,len = arguments.length;i < len;i++){ result*= arguments[i]; } return result; } //缓存代理 let proxy = (function(){ let cache = {}; reutrn function(){ let args = Array.prototype.join.call(arguments,','); if(args in cache){ return cache[args]; } return cache[args] = mult.apply(this,arguments); } })();
PHPデザインパターンのサービスロケーターパターン例の詳細説明
以上がJS の一般的なデザイン パターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。