一.什麼是模式.模式是一種可重複使用的解決方案,而反模式呢就是針對某個問題的不良解決方案。
js反模式常見範例
①向setTimeout和setInterval傳遞字串,而不是函數,這會觸發eval()的內部使用。
②在全域上下文中定義大量的變數污染全域命名空間
③修改Object類別的原型
④以內聯形式使用js,嵌入在HTML檔案中的js程式碼是無法包含在外部單元測試工具中的。
⑤濫用document.write,如果在頁面載入完成後執行docume.write,它會重寫我們所在的頁面,可以使用document.creatElement代替的話就盡量不用docume.write。
二.設計模式的類別
(一).工廠(Factory)模式(簡單與複雜)
簡單來說就是封裝後的程式碼,簡單的工廠模式是很好理解的,關於它的作用,就是利用物件導向的方法,把一些物件封裝,使一些佔用空間多的,重複的程式碼封裝起來。實作方法非常簡單,也就是在函數內建立一個對象,給對象賦予屬性以及方法再將對象傳回即可。這種方法 就是為了解決實例化物件產生大量重複的問題。
function creatper(name,age){ var per=new Object(); //原料 //加工 per.name=name; per.age=age; per.sayHi=function(){ console.log(per.name+'已经有'+per.age+"岁"); } return per; //出厂 } var test1=creatper('lili',22); var test2 =creatper('mike',25);//第二个实例 test1.sayHi(); test2.sayHi(); console.log(test1.name);
可以看出,使用工廠模式,可以重複調用這個per函數來產生不同屬性值得對象,這就像工廠一樣,批量生產,裡面的原料,加工,出廠都很清晰。但你會發現工廠模式是無法辨識物件的類型,因為全都是object,不像Date,Array等。
何時使用工廠模式?
Factory模式主要在以下場景使用:
①當物件或元件涉及高複雜性時
②當需要根據所在的不同環境輕鬆產生物件的不同實例時
③當處理許多共享相同屬性的小型物件或元件時
(二).建構器(Constructor)模式
ECMAScript 中可以採用建構子(建構方法)可用於建立特定的對象。 此模式正好可以解決以上的工廠模式無法辨識物件實例的問題。
function Student(name,age,classa){//构造函数模式 this.name = name; this.age = age; this.classa = classa; this.run = function () { console.log(this.name+ this.age+ "岁上"+this.classa +"!"); } } var Benz = new Student('Lili',22,'初三'); var BMW = new Student("Mike",25,"初一"); console.log(Benz instanceof Student); //很清晰的识别他从属于Student Benz.run(); BMW.run();
由程式碼可以看出,於工廠模式除了函數名稱不同以外,a.建構函式方法沒有顯示的建立物件(new Object()),b.直接把屬性和方法賦值給了this物件,c.沒有return語句。能夠辨識物件(這正是建構函式模式勝於工廠模式的地方)。注意補充:建構函數的方法規格:1.函數名稱和實例化建構名相同且大寫2.透過建構函式建立物件,必須使用 new 運算子。
既然透過建構子可以建立對象,那麼這個物件是哪裡來的, new Object()在什麼地方執行了?執行的過程如下:
1.當使用了建構子,並且new 建構子(),那麼就後台執行了new Object();
2.將建構函式的作用域給新對象,(即new Object()創建的物件),而函數體內的this 就代表new Object()出來的物件。
3.執行建構函式內的程式碼;
4.傳回新物件(後台直接回傳)。
(三).原型模式
js規定每一個建立的函數都有prototype(原型)屬性,這個屬性是指針,指向一個對象,而這個對象的用途是包含所有由特定類型的實例所共享的屬性和方法,使用原型物件就可以讓所有實例物件均包含這些屬性及方法。
function Per(){} Per.prototype.name='小米'; Per.prototype.age=22; Per.prototype.course=['php','javascript','java','C#']; Per.prototype.say=function(){ console.log(this.name+"有"+this.age+"岁,学习了"+this.course+"等课程。"); } var per1=new Per(); var per2=new Per(); per1.name='小林'; per1.course.push('Html5'); per1.say(); per2.say(); per2.course.pop();
關於原型模式的缺點,我想也是很明顯的,它省略了建構函式傳遞初始化參數這一環節,結果所有實例都在預設情況下取得了相同的屬性值,雖然你可以在後來做出更改,但一點都不方便,這樣還不是最大的問題,原型模式最大的問題是在於共享的本性所導致的,由於共享,因此一個實例修改了引用,另一個也隨之更改了屬性。因此一般不會單獨使用原型模式。
(四).帶原型的Constructor(建構器)= 原型模式+建構器模式
function Per(name,age,course){ this.name=name; this.age=age; this.course=course; } Per.prototype.say=function(){ console.log(this.name+"有"+this.age+"岁,学习了"+this.course+"等课程。"); } var per1=new Per('Make',22,['C#','java','PHP','Javascript']); var per2=new Per('小高',21,['oracle','mysql','nodejs','html5']); per1.say();//Make有22岁,学习了C#,java,PHP,Javascript等课程。 per2.say();//小高有21岁,学习了oracle,mysql,nodejs,html5等课程。 per1.course.pop(); per1.say();//Make有22岁,学习了C#,java,PHP等课程。 per2.say();//小高有21岁,学习了oracle,mysql,nodejs,html5等课程。
從上面分析:建構子用來定義實例的屬性,而原型模式用於定義方法和一些共享的屬性。每個實例都會有自己的屬性,但同時又共享方法,最大限度的節省了記憶體。另外這種模式也支援傳遞初始參數。使用最廣泛。
相關推薦:
以上是JavaScript工廠模式、原型模式、建構器模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!