上一主題下一主題
«12345»Pages: 1/16     Go
關鍵字
主題 : JavaScript OOP你現在還不懂,真OUT了!
級別: VIP四級

UID: 230365
精華: 12
發帖: 314
威望: 3432 點
學點: 380 點
貢獻: 2 點
好評: 1 點
學幣: 0 個
注冊時間: 2010-04-16
最后登錄: 2014-09-25
樓主  發表于: 2014-05-06 15:50||

1 JavaScript OOP你現在還不懂,真OUT了!

管理提醒: 本帖被 zylzyl 設置為精華(2014-05-07)
全面深入J****aScript OOP面向對象編程(史上最全面通俗易懂):點此了解詳情
s``L?9  
ri`|qy6! |  
g"f^YEQ_  
        前段時間,認識的一學生,已經工作了近三年,J****a,.net都有****過****發,去淘寶面試,回來后跟我聊,很受打擊,說面試他的人其他的問的不多,就是對他的J****aScript語言感興趣,但問他的即不是Jquery,也不是EasyUI,ExtJs等富客戶端的東西,直接問JS最原生的特性及JS OOP相關的東西,他搞了這么多年****發,平時對jquery用的很熟,對JS基本會用,遇到效果了,網上找找,拿過來修修改改,湊合能用就行,至于JS的OOP,什么封裝,閉包,原型鏈,JS的繼承等幾乎是一點也不懂,結果面試的結果可想而知了。 C"WZsF^3  
J6P Tkm}^  
      其實,聽完他講這些,我一點都不覺得奇怪,現在的軟件****發逐漸向B/S端,移動****發方向發展,但不管哪個方向,如果要想****出一些高性能,高質量的程序,幾乎對JS都會有著很高的要求,會一點JS對于普通 ****網站可能就夠用了,但是如果涉及到用戶對體驗要求很高,瀏覽器的兼容性要求高及一些特殊的領域如:GIS,自主****發工作流,繪制線路圖等方面應用時,對JS的要求肯定會是相當高,而且這類人員的工資待遇也會相當高,****一個Web****發高手,或者是一個Web****發的老鳥的話,也一定會是要求對JS非常精通,而精通的前提就是要求理解并會使用JS OOP進行客戶端技術****發。 nVD YAg'  
\)WjkhG<w#  
        本人有幸在10年前就從事過純客戶端產品的****發,很早接觸JS及JS OOP,對這方面有一些自己的研究和心得,感覺網上這方面的資料雖然很多,但不系統,不完整,不成體系,接下來,我想快速的整理一下網上資料,讓很多從來沒有接觸過JS OOP概念的朋友們,快速了解什么是JS OOP, 它的封裝、繼承、多態是怎么實現的,****一個掃盲。 C3gz)!3  
;zODp+4@Q  
一、你必須知道的 EG6fC4rfC  
1) 字面量 TXv#/@  
2) 原型 WH*&MIjAr/  
3) 原型鏈 k9]n/  
4) 構造函數 eNb =`  
5) 穩妥對象(沒有公共屬性,而且其方法也不引用this的對象。穩妥對象適合用在安全的環境中和防止數據被其它程序改變的時候) {wySH[V  
V-0Y~T  
二、****始創建對象吧 K~R{q +  
<1>: 首先來看兩種最基本的創建對象的方法 M-hnB t  
1> 使用Object創建對象 ;p8xL)mUP  
復制代碼
  1. var o = new Object();
  2. o.sname = 'JChen___1';
  3. o.showName = function(){
  4.     return this.sname;
  5. }
F_`Gs8- VH  
2> 使用對象字面量創建對象 aL}_j#m{  
復制代碼
  1. var o = {
  2.     name: 'JChen___2',
  3.     getName: function(){
  4.         return this.name;
  5.     }
  6. }
A[MEtI=Q J  
但是這兩個方式有個明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。 '"Gi&:*nQ<  
|>)mYLN!y  
<2> 接下來看看幾種創建對象的模式吧 T=vI'"w  
1>工廠模式 *RhdoD|a  
wuCODz@~  
復制代碼
  1. function create(name){
  2.     var o = new Object();
  3.     o.name = name;
  4.     o.sayName = function(){
  5.         return this.name;
  6.     };
  7.     return o;
  8. }
  9. var p1 = create('JChen___');
+FI]0r  
XQ>m8K?\d  
工廠模式也有一個缺點:就是沒有解決對象識別的問題(即怎樣知道一個對象的類型)。 ?uQpt(  
R 4?/7  
2> 構造函數模式 #\qES7We 6  
Gwe9< y  
復制代碼
  1. function create2(name){
  2.     this.name = name;
  3.     this.sayName = function(){
  4.         return this.name;
  5.     };
  6.     //this.sayName = sayName;
  7. }
  8. //function sayName(){ return this.name};
  9. var p1 = new create2('JChen___4');
rnUe/HjH  
38 F8(QU{  
構造函數模式也有一個缺點:就是每個方法都要在每個實例上創建一遍。 occ}|u  
當然我們可以用上面的兩行注釋掉了代碼來屏蔽上面那個缺點。 t+ t&eg  
但是……,我們又產生了一個新問題——全局變量。如果有很多方法,我們豈不是要定義很多個全局變量函數。這是個可怕的問題。 Y&nY]VV  
U<$|ET'  
3> 原型模式 -4.+&'  
1) 普通方法 sHNt>5p  
復制代碼
  1. function create3(){}
  2. create3.prototype.name = 'JChen___5';
  3. create3.prototype.sayName = function(){
  4.     return this.name;
  5. };
  6. var p1 = new create3();
 TeHR,GB  
]'Bz%[C)  
2) 原型字面量方法——我姑且這么稱吧 ~~&M&Fe  
s&4Y+dk93  
復制代碼
  1. function create3(){}
  2. create3.prototype = {
  3.     constructor: create3, //我們要設置它的constructor,如果它很重要
  4.     name: 'JChen___5',
  5.     sayName: function(){
  6.         return this.name;
  7.     }
  8. };
  9. var p1 = new create3();
IIzdCa{l  
C。eZcNJG  
原型的缺點: ]`%cTdpLj  
1): 不能傳參 Xh5 z8  
2): 共享了變量 HQ"D>hsuU  
` 6PdMvF  
4> 構造+原型(模式) /J ^yOR9  
yA~W|q(/V  
復制代碼
  1. function create4(name){
  2.     this.name = name;
  3. }
  4. create4.prototype.sayName = function(){
  5.     return this.name;
  6. }
  7. var p1 = new create4('JChen___6');
J}BS/Tr}=  
這種模式是目前使用最廣泛、認同度最高的一種創建自定義類型的方法。 L49`=p<  
rQU;?[y  
5> 動態原型模式 Xr-eDUEi  
CQS34&G$a  
復制代碼
  1. function create5(name){
  2.     this.name = name;
  3.     if(typeof this.sayName != 'function'){
  4.         create5.prototype.sayName = function(){
  5.             return this.name;
  6.         }
  7.     }
  8. }
  9. var p1 = new create5('JChen___7');
)tB mSVprl  
13Q|p,^R  
這種方法確實也是十分完美的一種方法。 ACs?m\$Q  
tJc9R2  
6> 寄生構造函數模式 ^8DC W`V  
DJhi>!xJ  
復制代碼
  1. function create6(name){
  2.     var o = new Object();
  3.     o.name = name;
  4.     o.sayName = function(){
  5.         return this.name;
  6.     }
  7.     return o;
  8. }
  9. var p1 = new create6('JChen___8');
%c):^;6p  
。Um。dXBYU  
注意那個return o。構造函數在不返回值的情況下,會返回新對象實例。而通過在構造函數的末尾加入return 語句,可以重寫調用構造函數時返回的值。 S Bs_rhe  
這個種用法可以用在,假設我們想創建一個具有額外方法的特殊數組。由于不能直接修改Array的構造函數,因此可以使用這個模式。 XDU&Z2A  
L9(fa+$+#  
復制代碼
  1. function specialArray(){
  2.     var values = new Array();
  3.     values.push.apply(values, arguments);
  4.     values.join2 = function(){
  5.         return this.join('|');
  6.     };
  7.     return values;
  8. }
  9. var colors = new specialArray('red', 'blue', 'green');
  10. colors.join2();//returned: red|blue|green
\)pk/  
mJl|dk_ c  
7>穩妥構造函數模式 p \1-。  
穩妥構造函數遵循與寄生構造函數類似的模式,但是有兩點不同: &jr'vS[b  
一是新創建對象的實現方法不引用this UT%^!@u  
二是不使用new操作符調用構造函數。 f3h^R20qmO  
46Vx)xX  
復制代碼
  1. functioncreate7(name){
  2.     var o = new Object();
  3.     var age = 12;                //私有變量
  4.     o.sayName = function(){      //私有方法
  5.         return name + ' ' + age;
  6.     }
  7.     returno;
  8. }var p1 = create7('JChen___9');
|}t[- a  
hT]\*},  
二、JS繼承的6種方法 a2/!~X9F  
1> 原型鏈繼承 HsO4C)/  
原型鏈繼承是通過創建Super的實例,并將該實例賦值給Sub.prototype來實現的。 6"b =aPTi  
實現的本質是:重寫子類型的原型對象,代之以超類型的實例。 lOYzo  
F<VoPqHq  
復制代碼
  1. function Super(){
  2.     this.name = 'JChen___';
  3. }
  4. Super.prototype.getSuperName = function(){
  5.     return this.name;
  6. }
  7. function Sub(){
  8.     this.subname = 'JChen___son';
  9. }
  10. Sub.prototype = new Super(); //原型繼承體現在這里
  11. Sub.prototype.getSubName = function(){
  12.     return this.subname;
  13. }
  14. var instance = new Sub();
Q)#+S(TG  
Tapj7/0`   
注意:此時instance.constructor現在指向的是Super的,這是因為Sub.prototype指向了Super.prototype,而Super.prototype.constructor = Super。 PQDW Y  
原型鏈的問題:類似于利用原型創建對象,原型共享的特性也是原型鏈繼承的最大問題。 :=3Ty]e  
g)nsP  
2> 借用構造函數繼承 XDRw![H,~  
在解決原型中包含引用類型值所帶來的問題的過程中,我們****始使用一種叫****借用構造函數的技術。 gZ8n[zxf6  
這種技術的基本思想相當簡單:在子類型構造函數的內部調用超類型構造函數。 0rP`BK|  
這樣一來,就會在新子類對象上執行超類函數中定義的所有對象初始化代碼。結果,每個子類的實力都會有自己的超類中屬性的副本了。 wGr5V!  
O0 [.*xG  
復制代碼
  1. function Super2(name){
  2.     this.colors = ['red', 'blue'];
  3.     this.name = name;
  4. }
  5. function Sub2(){
  6.     Super2.call(this, 'JChen___2'); //借用構造函數技術體現在這里
  7.     this.age = 29;
  8. }
  9. var instance1 = new Sub2();
  10. instance1.colors.push('black');
  11. var instance2 = new Sub2();
  12. instance2.colors.push('green');
nO.RB#I$F  
[oqb@J2  
借助構造函數繼承的問題: (pJ-_w' G  
1): 方法都在構造函數中定義,無法復用。 . Lbu[  
2): 在超類型的原型中的方法對子類是不可見的。 RsU!mYs:H  
9M8 n  
3> 組合繼承(原型+借用構造) V/"P};n  
組合繼承指的是將原型鏈和借用構造函數的技術組合到一塊,從而發揮二者之長的一種繼承模式。 ]#x!mZ!  
組合繼承的思路:使用原型鏈實現對方法和屬性的繼承,通過借用構造函數實現對實例屬性的繼承。 $ReoIU^<  
d)d\h`=Z  
復制代碼
  1. function Super3(name){
  2.     this.name = name;
  3.     this.colors = ['red', 'blue'];
  4. }
  5. Super3.prototype.sayName = function(){
  6.     return this.name;
  7. }
  8. function Sub3(name, age) {
  9.     Super3.call(this, name);
  10.     this.age = age;
  11. }
  12. Sub3.prototype = new Super3(); //解決借用構造函數技術的缺點
  13. Sub3.prototype.constructor = Sub3; //糾正原型繼承改變了的構造函數
  14. Sub3.prototype.sayAge = function(){
  15.     return this.age;
  16. }
;iEr+  
kB:6e7D|[  
組合繼承避免了原型鏈和借用構造函數的缺陷,融合了他們的優點,成為J****aScript中最常用的繼承模式。 <O+T 4.z  
組合繼承的問題:兩次調用超類構造函數。 vG;)(.:  
] /w: 5o#  
4> 原型式繼承 , z8<[Q-#  
原型式繼承的思路:借助原型可以基于已有的對象創建新對象,同時還不必因此創建自定義類型。 !5FZxmUup  
Tp-<!^o4  
復制代碼
  1. function object(o){ //原型式繼承的關鍵
  2.     function F(){}
  3.     F.prototype = o;
  4.     return newF();
  5. }
  6. var person = {
  7.     name: 'JChen___4',
  8.     colors: ['blue']
  9. }
  10. var person1 = object(person);
  11. person1.name = 'JChen___4___2'person1.colors.push('red');
  12. var person2 = object(person);
  13. person2.name = 'JChen___4___3';
  14. person2.colors.push('green');
afE`GG-  
_\mMgZu  
原型式繼承的問題:同原型鏈一樣,他也有共享的劣勢。 (4ueO~jb $  
m 3k}iIU7  
5> 寄生式繼承 N i\*<:_  
寄生式繼承的思路:創建一個僅用于封裝繼承過程的函數,該函數內部以某種方式來增強對象,最后再返回該對象 UTT7a"  
%UV'HcO/gp  
復制代碼
  1. function createAnother(origin){ //寄生式繼承的關鍵
  2.     var clone = object(origin);
  3.     clone.sayHi = function(){
  4.         return 'Hi';
  5.     };
  6.     return clone;
  7. }
  8. var person = {
  9.     name: 'JChen___4',
  10.     colors: ['blue']
  11. }
  12. var person1 = createAnother(person);
P01o:/}  
kWkAfzf4a  
寄生式繼承的問題:像構造函數一樣,由于不能****到函數的復用而降低效率。 -^a?]`3_v  
vbXZZ  
6> 寄生組合式繼承 WcE{1&PXx  
寄生組合式繼承:通過借用構造函數來借用屬性,通過原型鏈的混成形式來繼承方法。 $mS] K!\  
其背后的思想是:不必為了指定子類型的原型而調用超類型的構造函數,我們需要的無非就是超類型的一個副本而已。 \*24NB  
 ^##tk  
復制代碼
  1. function object(o){
  2.     function F(){}
  3.     F.prototype = o;
  4.     return new F();
  5. }
  6. function inheritProto(subType, superType){ //避免第一調用構造函數的關鍵
  7.     var proto = object(superType.prototype);
  8.     proto.constructor = subType;
  9.     subType.prototype = proto;
  10. }
  11. function Super6(name){
  12.     this.name = name;
  13.     this.colors = ['red', 'blue'];
  14. }
  15. Super6.prototype.sayName = function(){
  16.     return this.name;
  17. }
  18. function Sub6(name, age){
  19.     Super6.call(this, name);
  20.     this.age = age;
  21. }
  22. inheritProto(Sub6, Super6);
  23. Sub6.prototype.sayAge = function(){
  24.     return this.age;
  25. }
  26. var instance1 = new Sub6('JChen___6', '12');
  27. instance1.colors.push('black');
Tno[LP,  
]6#7TT  
****發人員普遍認為寄生組合式繼承是引用類型最理想的繼承范式。 H jho!np  
三、總結 ?$:;hGO.<~  
這就是J****aScript中的6種繼承方式,如果大家能夠畫出每個繼承的原型鏈關系圖,那么繼承就是小菜一碟了 <X5'uve  
了解了這些,你基本上對OOP有了一個入門,補充說明,以上內容均來自互聯網,非本人原創。不過可能對于JS OOP重來沒有接觸過的同學看起來還是會覺得有些吃力,我最近也在整理這方面的資料并錄制相關方向的課程,目錄列下: 7x,c)QES`  
復制代碼
  1. 1. part1_c05_01_01_前言-為什么你要學習J****aScript2. part1_c05_01_02_JS****發神器-WebStorm高級使用技巧
  2. 3. part1_c05_01_02_使用方括號([ ])引用對象的屬性和方法
  3. 4. part1_c05_01_03_Web瀏覽器中J****aScript調試技巧
  4. 5. part1_c05_02_01_用定義函數的方式定義類
  5. 6. part1_c05_02_02_使用new操作符獲得一個類的實例
  6. 7. part1_c05_02_03_動態添加、修改、****JS對象的屬性和方法
  7. 8. part1_c05_02_04_使用大括號({ })語法創建無類型對象
  8. 9. part1_c05_02_05_prototype原型對象
  9. 10. part1_c05_03_01_初識j****ascript函數對象
  10. 11. part1_c05_03_02_函數對象和其他內部對象的關系
  11. 12. part1_c05_03_03_將函數作為參數傳遞
  12. 13. part1_c05_03_04_傳遞給函數的隱含參數_arguments
  13. 14. part1_c05_03_05_函數的apply、call方法的運用
  14. 15. part1_c05_03_06_深入認識J****aScript中的this指針
  15. 16. part1_c05_04_01_理解j****ascript中類的實現機制
  16. 17. part1_c05_04_02_使用prototype對象定義類成員
  17. 18. part1_c05_04_03_J****aScript類的設計模式優化
  18. 19. part1_c05_05_01_J****aScript類的公有成員與私有成員
  19. 20. part1_c05_05_02_J****aScript類的靜態成員
  20. 21. part1_c05_06_01_在J****aScript中利用for(…in…)語句實現反射
  21. 22. part1_c05_06_02_JS中利用反射動態設置CSS樣式高級技巧
  22. 23. part1_c05_07_01_利用共享prototype實現繼承的用法與缺陷
  23. 24. part1_c05_07_02_利用反射機制和prototype實現JS繼承
  24. 25. part1_c05_07_03_參考prototype.js框架自實現JS中的類的繼承
  25. 26. part1_c05_07_04_Prototype.js源碼剖析與使用示例
  26. 27. part1_c05_08_01_在J****aScript中實現抽象類與虛方法
  27. 28. part1_c05_08_02_J****aScript中使用抽象類的示例
  28. 29. part1_c05_09_01_自定義實現JS中最簡單的事件設計模式
  29. 30. part1_c05_09_02_重構自定義J****aScript事件****程序解決事件傳參問題
  30. 31. part1_c05_09_03_重構自定義J****aScript事件****程序多事件綁定機制
  31. 32. part1_c05_10_01_J****aScript面向對象綜合示例
  32. 33.part1_c05_11_01_JS壓縮與混淆工具(JSA、JSCompressor、Google Closure Compiler )
  33. 34. part1_c05_11_02_JS高級調式工具(FireBugLite)
 @%8Xa7+  
學完這套課程你能得到東西: [5KzawV  
想學習JS的調試,性能優化,及一些優秀前端工具的使用 bu&x& M*  
對JS的應用有更深層次了解 XI>|"*-l  
對JS OOP思想有一定程度的了解 M@LI(;  
自己能動手寫一個基于JS OOP的簡單框架 .'+*>y!  
對于后繼jquery,easyui,extjs等富客戶端的學習打好基礎 5)%bnLxn  
能用于J****a,PHP,.NET****發,移動****發工作中 W6=j^nv  
上述課程的錄制正在進行中,歡迎大家多對課程提寶貴意見,以****內容,早日出來,以饗讀者。 H[K(Tt4<&  
另附:已經講完的部分內容,大家可以下載下來看下,以加深對JS OOP的理解 fa~u<m   
附下載: >o\s'i[  
5. part1_c05_02_01_用定義函數的方式定義類 ;THb6Jz/+  
6. part1_c05_02_02_使用new操作符獲得一個類的實例 B5- G.Z  
7. part1_c05_02_03_動態添加、修改、****JS對象的屬性和方法 /hC[>t<  
8. part1_c05_02_04_使用大括號({ })語法創建無類型對象 vSu|!Xb]  
9. part1_c05_02_05_prototype原型對象 K2= `.  
10. part1_c05_03_01_初識j****ascript函數對象 i{['18Q$F3  
11. part1_c05_03_02_函數對象和其他內部對象的關系 mY}_9rTn|  
12. part1_c05_03_03_將函數作為參數傳遞 35 Y#eU2]  
13. part1_c05_03_04_傳遞給函數的隱含參數_arguments 3 #fOrNU2  
14. part1_c05_03_05_函數的apply、call方法的運用 I|RMxx y;  
15. part1_c05_03_06_深入認識J****aScript中的this指針 VxlK:*t`  
鏈接: ;(]O*{F7k  
密碼:
本部分內容設定了隱藏,需要回復后才能看到
M 5mCG  
y:FxX8S$'e  
全面深入J****aScript OOP面向對象編程(史上最全面通俗易懂):點此了解詳情
級別: VIP五級

UID: 464190
精華: 0
發帖: 1
威望: 8 點
學點: 13 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2014-05-07
最后登錄: 2015-06-24
沙發(1樓)  發表于: 2014-05-07 19:27||

very very thank you
級別: 北風技術員

UID: 223452
精華: 0
發帖: 55
威望: 534 點
學點: 4 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2010-03-16
最后登錄: 2014-05-10
板凳(2樓)  發表于: 2014-05-10 23:08||

樓主寫的很好,學習了
級別: VIP四級

UID: 260541
精華: 0
發帖: 44
威望: 394 點
學點: 15 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2010-09-16
最后登錄: 2015-04-26
地板(3樓)  發表于: 2014-05-11 00:56||

非常好啊,頂
級別: 終身會員

UID: 8195
精華: 0
發帖: 129
威望: 612 點
學點: 46 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2008-06-13
最后登錄: 2019-06-26
地下室(4樓)  發表于: 2014-05-11 18:05||

看看啊看卡看
級別: 終身會員

UID: 8195
精華: 0
發帖: 129
威望: 612 點
學點: 46 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2008-06-13
最后登錄: 2019-06-26
下水道(5樓)  發表于: 2014-05-11 20:19||

老師的發布計劃 怎么的?
級別: VIP四級

UID: 230365
精華: 12
發帖: 314
威望: 3432 點
學點: 380 點
貢獻: 2 點
好評: 1 點
學幣: 0 個
注冊時間: 2010-04-16
最后登錄: 2014-09-25
6樓  發表于: 2014-05-12 13:33||

計劃會是6月份和我的一套大型的商業課程“基于ASP.NET MVC 4 +Knockout.JS+Web API+FluentData+EasyUI 技術實現Web通用商業****發框架” 官網預****,到時這門課程也會單獨拿出來****,請大家關注北風論壇,謝謝各位的支持
級別: 北風愛好者

UID: 464854
精華: 0
發帖: 2
威望: 4 點
學點: 6 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2014-05-13
最后登錄: 2014-08-04
7樓  發表于: 2014-05-13 12:05||

很好很強大 我喜歡。
級別: 北風愛好者

UID: 424923
精華: 0
發帖: 1
威望: 2 點
學點: 2 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2013-05-31
最后登錄: 2014-05-13
8樓  發表于: 2014-05-13 15:47||

看看 thank you very much
級別: 北風愛好者

UID: 465177
精華: 0
發帖: 1
威望: 2 點
學點: 4 點
貢獻: 0 點
好評: 0 點
學幣: 0 個
注冊時間: 2014-05-15
最后登錄: 2014-05-15
9樓  發表于: 2014-05-15 18:27||

我是來拿資源的,嘻嘻
上一主題下一主題
«12345»Pages: 1/16     Go
2019比较好网赚项目 159彩票app下载 2019哪些网赚是真的 2019年最新挂机网赚 介绍下靠谱的网赚项目 金旋风网赚 支付宝网赚是真的吗 新凤凰彩票注册 吉林快3 2019挂机国内网赚软件