Rumah >hujung hadapan web >Soal Jawab bahagian hadapan >Penjelasan klasik JavaScript tentang corak reka bentuk (contoh terperinci)
Artikel ini membawa anda pengetahuan yang berkaitan tentang corak reka bentuk dalam JavaScript, termasuk corak tunggal, corak gabungan, corak pemerhati, dsb. Saya harap ia akan membantu anda.
Corak reka bentuk ialah satu set penyelesaian optimum yang direka untuk menyelesaikan masalah tertentu.
Berorientasikan objek - memberi lebih perhatian kepada objek - cari cara terbaik untuk mentakrifkan objek dan menambah sifat dan kaedah pada setiap objek
Penyelesaian terbaik ditemui - ialah corak reka bentuk
untuk Untuk masalah yang berbeza , kami akan mempunyai penyelesaian terbaik yang berbeza - Corak Reka Bentuk
Corak reka bentuk biasa:
Sambungan pangkalan data - berbilang fungsi perlu mengendalikan pangkalan data - menyambung semula pangkalan data - 1000 fungsi, menyambung ke pangkalan data 1000 kali
Fungsi pendaftaran, setiap pendaftaran memerlukan operasi pangkalan data - 1,000 orang mendaftar pada masa yang sama
Pangkalan data mysql mempunyai had sambungan: ia hanya boleh menyokong maksimum 200 sambungan pada masa yang sama
Kami menyambung sekali Pangkalan Data, mendapatkan sambungan, mengendalikan pangkalan data beberapa kali, menggunakan sambungan ini untuk mengendalikannya
Cara mengendalikannya, biarkan pernyataan pangkalan data dilaksanakan beberapa kali menggunakan sambungan yang sama - kami boleh mereka bentuk corak reka bentuk
Mod reka bentuk: Tentukan kelas ini akan mendapat sambungan selepas menjadi baharu Setiap kali anda melaksanakan pernyataan pangkalan data pada masa hadapan, anda boleh mendapatkan sambungan daripada kelas ini
Mod Singleton. Anda hanya boleh mendapatkannya daripada satu kelas Objek - tidak kira berapa kali kelas ini dikendalikan, semua objek sambungan akhir adalah objek yang sama
Semua objek yang dicipta oleh kelas mempunyai sifat dan kaedah yang sama. . Sebagai contoh, merangkum kelas dan meletakkan beberapa fungsi pengendalian yang biasa digunakan sebagai kaedah, dan gunakan objek yang sama untuk memanggil kaedah ini setiap kali
Biasanya, setiap objek yang dicipta oleh kelas adalah berbeza .
class Carousel{ }var a = new Carousel();var b = new Carousel();console.log(a === b); // false
Mod tunggal adalah untuk menjadikan kedua-dua objek sama, iaitu, kelas akan sentiasa mempunyai hanya satu objek contoh
var single = (function(){ class Carousel{ } var res = undefined; return function(){ if(!res){ res = new Carousel(); } return res; }})();var s1 = single();var s2 = single();console.log(s1 === s2); // true
Pembolehubah P terdedah kepada pembolehubah global akan Menyebabkan pencemaran global
Gunakan penutupan untuk menyelesaikan masalah mentakrifkan semula p setiap kali
Kod teras mod tunggal:
function Person(){}function fn(Person){ var p; return function(){ if(!p){ p = new Person; } return p; }}var f = fn(Person)var p1 = f()var p2 = f()
Senario aplikasi mod tunggal berada dalam perpustakaan alat pembungkusan.
Contoh: Merangkum dan merangkum perpustakaan alat
Pustaka alat pengekapsulan aplikasi mod tunggal
工具库中会有很多的方法 - 方法每次的使用 应该是同一个对象使用的,而不是应该每次都有一个新对象在使用工具
// var t = new Tool; // t.setCookie('username', 'zs', 20); const Tool = (function () { class Tool { constructor() { if (window.getComputedStyle) { this.flag = true; } else { this.flag = false; } } /获取节点属性 getStyle(ele, attr) { if (this.flag) { return window.getComputedStyle(ele)[attr]; } else { return ele.currentStyle[attr]; } } getStyle(ele, attr) { 尝试一段代码 不知道会不会报错 尝试成功 后面代码没有什么事 尝试失败 会报错 被cathch 捕获到 会将错误信息放到err参数里 catch{} 里可以处理这个错误 也可以不处理这个错误对上面的错误代码进行补救 错误不会再浏览器里报错 try { return window.getComputedStyle(ele)[attr]; } catch (err) { return ele.currentStyle[attr]; } } // 设置节点css属性 setStyle(ele, styleObj) { for (let attr in styleObj) { ele.style[attr] = styleObj[attr]; } } // 设置cookie setCookie(key, value, second, path = '/') { let data = new Date(); date.setTime(date.getTime() - 8 * 3600 * 1000 + second * 1000); document.cookie = `${key}=${value};expires=${date};path=${path}`; } } var tool; return (function () { if (!tool) { tool = new Tool(); } return tool; })(); })();
Mod gabungan ialah Buat pelancar. Selepas beberapa kelas dimulakan, mereka menggunakan kaedah dengan nama yang sama untuk bermula Pada masa ini, anda boleh membuat pelancar untuk memulakan berbilang kelas bersama-sama.
class Carousel{ init(){ console.log("轮播图开始运行"); }}class Tab{ init(){ console.log("选项卡开始运行"); }}class Enlarge{ init(){ console.log("放大镜开始运行"); }}// 这3个类要运行起来需要各自实例化,并调用每个类中的init方法,此时就可以使用组合模式做一个启动器
Pelancar pengeluaran mod gabungan:
class Starter{ constructor(){ this.arr = []; // 定义一个数组 } add(className){ this.arr.push(className); // 将这个多个类放进数组 } run(){ for(var i=0;i<this.arr.length><hr> <h3>1.4 Mod Terbit dan langgan</h3> <p>https://blog.csdn.net/weixin_44070254/article /details/117574565?spm=1001.2014.3001.5501</p> <p>Seseorang melanggan dan ada yang menerbitkan<br> Terbit dan melanggan model: pemerhati diperlukan dan pemerhatian diperlukan Jika pemerhati mendapati status yang diperhatikan berubah, ia akan Perlu melaksanakan tugas <br> Tentukan pemerhati: </p> <pre class="brush:php;toolbar:false">class Observer{ // 观察者有名字和任务 constructor(name,task){ this.name = name this.task = task }}// 定义班主任var bzr = new Observer('班主任',function(state){ console.log("因为"+state+",所以"+this.name+"罚站");})// 定义了一个年级主任var zr = new Observer('年级主任',function(state){ console.log("因为"+state+",所以"+this.name+"要找班主任");})// 被观察者class Subject{ // 有自己的状态 constructor(state){ this.state = state // 观察者们 this.observer = []; } // 添加被观察者 add(...arr){ this.observer = this.observer.concat(arr) } // 改变状态 changeSate(state){ this.state = state // 触发观察者的任务 for(let i=0;i<this.observer.length><p>Corak pemerhati, juga dikenali sebagai corak publish-subscribe. Ia bermaksud seseorang sentiasa memantau sesuatu perkara apabila perkara itu akan melakukan sesuatu tingkah laku, orang itu akan memberitahu fungsi untuk melaksanakan operasi tingkah laku itu. </p> <p>Contoh: Selepas kod acara ditulis, acara ini sebenarnya sentiasa memantau tingkah laku pengguna pada halaman Setelah pengguna mencetuskan acara ini, fungsi dipanggil untuk mengendalikan acara. </p> <pre class="brush:php;toolbar:false">p.addEventListener("click",function(){}); // 这个事件写好以后,就一直在页面中监控用户行为,用户点击这个元素的时候,就调用函数
Corak pemerhati ialah operasi yang serupa Tujuan menulis corak pemerhati adalah untuk mengikat peristiwa tersuai kepada data bukan elemen.
Contoh: Ikat peristiwa abc ke obj
Analisis:
Ikat peristiwa pada elemen Terdapat kaedah mengikat, syarat pencetus dan tidak mengikat.
Ikat acara tersuai pada objek. Jadi bagaimana untuk mengikat acara ini, cara mencetuskannya, dan cara menyahikat acara ini.
Jadi:
, satu jenis acara boleh terikat kepada berbilang pengendali.
Cara untuk mengikat berbilang fungsi kepada satu jenis acara melalui acara tersuai objek.
Jadi:
memerlukan ruang untuk menyimpan fungsi pemprosesan yang sepadan dengan jenis acara.
class watch{ bind(){ } touch(){ } unbind(){ }}var w = new watch();
Pada masa ini, jika anda ingin mengikat acara dan fungsi pemprosesan pada objek ini, anda memerlukan jenis acara dan fungsi pemprosesan sebagai parameter, jadi anda perlu menghantarnya apabila memanggil Masukkan parameter sebenar
var w = new watch();w.bind("cl",a); // 给w对象绑定cl事件类型,执行a函数w.bind("cl",b); // 给w对象绑定cl事件类型,执行b函数function a(){ console.log("事件处理函数a");}function b(){ console.log("事件处理函数b");}
menerima parameter dalam kaedah bind dan menyimpan jenis acara dan fungsi pemprosesan dengan sewajarnya:
constructor(){ this.obj = {} // 存储格式:{事件类型:[函数1,函数2]}}bind(type,handle){ this.obj[type] = [handle]; // 对象存储方式{"cl":[a]}}
Jika anda mengikat satu lagi fungsi b pada acara ini, a yang asal akan ditimpa Oleh itu, anda harus menilai terlebih dahulu Jika tiada data dalam tatasusunan yang sepadan, letakkan sahaja, anda perlu tambahkan
bind(type,handle){ if(!this.obj[type]){ this.obj[type] = [handle]; // 对象存储方式{"cl":[a]} }else{ this.obj[type].push(handle); } }
Cetak hasil objek w:
绑定后的存储结果 |
---|
触发这个事件需要传入触发哪个事件类型
touch(type){ // 首先要判断,这个事件类型是否绑定,没有绑定不能触发 if(!this.obj[type]){ return false; }else{ // 将这个事件的所有绑定的处理函数一起调用 for(var i=0;i<this.obj><p>测试:</p> <table> <thead><tr class="firstRow"><th>触发测试</th></tr></thead> <tbody> <tr><td><img src="https://img.php.cn/upload/article/000/000/067/723219bbf42dba49705fd0fe49beab7d-1.png" alt="Penjelasan klasik JavaScript tentang corak reka bentuk (contoh terperinci)"></td></tr> <tr><td><br></td></tr> </tbody> </table> <p>这两个处理函数都没有参数,如果要传入参数的时候该怎么处理?</p> <p>触发事件的时候就要传入实参</p> <pre class="brush:php;toolbar:false">w.touch("cl","张三",20);
触发事件的方法就应该处理这些参数
touch(type,...arr){ // 因为参数不定长,所以使用合并运算符 // 首先要判断,这个事件类型是否绑定,没有绑定不能触发 if(!this.obj[type]){ return false; }else{ // 处理参数:模拟系统事件的参数事件对象,将所有参数都集中在一个对象中 var e = { type:type, args:arr } // 将这个事件的所有绑定的处理函数一起调用 for(var i=0;i<this.obj><p>添加一个带参数的处理函数,并触发事件执行:</p> <pre class="brush:php;toolbar:false">w.bind("cl",c); // 给w对象绑定cl事件类型,执行c函数w.touch("cl","张三",20);function c(e){ console.log("我是处理函数c,打印:姓名"+e.name+",年龄"+e.age);}
结果:
带参数的处理函数处理结果 |
---|
解绑也需要知道解绑的事件类型和处理函数
unbind(type,handle){ // 先判断是否绑定了这个事件 if(!this.obj[type]){ return false; }else{ // 从数组中将这个处理函数删除 for(var i=0;i<this.obj><p>解绑测试:</p> <table> <thead><tr class="firstRow"><th>解绑测试结果</th></tr></thead> <tbody> <tr><td><img src="https://img.php.cn/upload/article/000/000/067/723219bbf42dba49705fd0fe49beab7d-3.png" alt="Penjelasan klasik JavaScript tentang corak reka bentuk (contoh terperinci)"></td></tr> <tr><td><br></td></tr> </tbody> </table> <p>如果绑定事件的时候使用的匿名函数,就无法进行解绑了,所以再添加一个解绑事件所有处理函数的方法:</p> <pre class="brush:php;toolbar:false">clear(type){ if(!this.obj[type]){ return false; }else{ // 直接从对象中将这个属性删除 delete this.obj[type]; } }
观察者模式跟发布订阅模式不一样的地方在于,要有观察者和被观察者。
创建观察者:
// 创建观察者class Observer{ // 观察者有姓名和技能 - 技能是一个函数 constructor(name,skill){ this.name = name; this.skill = skill }}// 创建观察者var bzr = new Observer('班主任',function(state){ console.log('因为'+state+'叫家长')})var xz = new Observer('校长',function(state){ console.log('因为'+state+'叫班主任')})console.log(bzr,xz)
创建被观察者:
// 创建被观察者 class Subject{ // 被观察者有状态 和 观察者列表 constructor(state){ this.state = state this.observers = [] } // 添加观察者 addObserver(observer){ var index = this.observers.findIndex(v=>v === observer) if(index{ v.skill(this.state) }) } } // 删除观察者 delObserver(observer){ var index = this.observers.findIndex(v=>v === observer) if(index>=0){ this.observers.splice(index,1) } } } // 创建被观察者 var xm = new Subject('学习') // 添加观察者 xm.addObserver(bzr) xm.addObserver(xz) xm.addObserver(bzr) console.log(xm) // 改变状态 xm.setState('玩游戏')
一个问题有多种解决方案,且随时还可以有更多的解决方案,就是策略模式。例如:一个商品在售卖的时候,会有多种折扣方式,慢100减10元,满200减30元等…
商品活动:
满100减10
满200减30
满300打8折
策略模式:将折扣放在闭包中保存起来 - 通过闭包对折扣进行增删改查操作
正常的函数表达方式:
function fn(type,price){ if(type === '100_10'){ return price -= 10 }else if(type === '200_30'){ return price -= 0 }else{ return '没有这种折扣' }}fn('100_10',160)
这种方式,在添加折扣或删除折扣的时候总是需要修改原函数。
策略模式代码:
var calcPrice = (function(){ // 以闭包的形式存储折扣数据 var sale = { '100_10':function(price){ return price -= 10 }, '200_20':function(price){ return price -= 20 } } function calcPrice(type,price){ // 闭包中使用折扣 if(type in sale){ return sale[type](price) }else{ return '没有这个折扣' } } // 折扣函数添加属性 - 添加折扣 calcPrice.add = function(type,fn){ if(type in sale){ console.log('折扣存在') }else{ sale[type] = fn } } // 删除折扣 calcPrice.del = function(type){ if(type in sale){ delete sale[type] }else{ console.log('折扣不存在') } } return calcPrice})()var p = calcPrice('100_10',200)calcPrice.add('200_320',function(price){ return price -= 50})calcPrice.del('200_330')var p = calcPrice('200_320',200)console.log(p)
相关推荐:javascript学习教程
Atas ialah kandungan terperinci Penjelasan klasik JavaScript tentang corak reka bentuk (contoh terperinci). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!