上一主题下一主题
«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面向对象编程(史上最全面通俗易懂):点此了解详情
7&{[Y^R]"  
XonI   
R,KoymXP  
        前段时间,认识的一学生,已经工作了近三年,J****a,.net都有****过****发,去淘宝面试,回来后跟我聊,很受打击,说面试他的人其他的问的不多,就是对他的J****aScript语言感兴趣,但问他的即不是Jquery,也不是EasyUI,ExtJs等富客户端的东西,直接问JS最原生的特性及JS OOP相关的东西,他搞了这么多年****发,平时对jquery用的很熟,对JS基本会用,遇到效果了,网上找找,拿过来修修改改,凑合能用就行,至于JS的OOP,什么封装,闭包,原型链,JS的继承等几乎是一点也不懂,结果面试的结果可想而知了。 #ybtjsu'"U  
g=_@j`  
      其实,听完他讲这些,我一点都不觉得奇怪,现在的软件****发逐渐向B/S端,移动****发方向发展,但不管哪个方向,如果要想****出一些高性能,高质量的程序,几乎对JS都会有着很高的要求,会一点JS对于普通 ****网站可能就够用了,但是如果涉及到用户对体验要求很高,浏览器的兼容性要求高及一些特殊的领域如:GIS,自主****发工作流,绘制线路图等方面应用时,对JS的要求肯定会是相当高,而且这类人员的工资待遇也会相当高,****一个Web****发高手,或者是一个Web****发的老鸟的话,也一定会是要求对JS非常精通,而精通的前提就是要求理解并会使用JS OOP进行客户端技术****发。 Pq)C(Z  
>Sua:Uff  
        本人有幸在10年前就从事过纯客户端产品的****发,很早接触JS及JS OOP,对这方面有一些自己的研究和心得,感觉网上这方面的资料虽然很多,但不系统,不完整,不成体系,接下来,我想快速的整理一下网上资料,让很多从来没有接触过JS OOP概念的朋友们,快速了解什么是JS OOP, 它的封装、继承、多态是怎么实现的,****一个扫盲。 L[cl$ pYV  
Hv.n O-c  
一、你必须知道的 *:hHlH* t1  
1) 字面量 k\`~v$R3  
2) 原型 sQ>L3F ;A`  
3) 原型链 S6bW?8`  
4) 构造函数 Kitx%P`i  
5) 稳妥对象(没有公共属性,而且其方法也不引用this的对象。稳妥对象适合用在安全的环境中和防止数据被其它程序改变的时候) Zm~oV?6  
'+*{u]\  
二、****始创建对象吧 *='J>z.]  
<1>: 首先来看两种最基本的创建对象的方法 j`pX2S  
1> 使用Object创建对象 gS$?#!f  
复制代码
  1. var o = new Object();
  2. o.sname = 'JChen___1';
  3. o.showName = function(){
  4.     return this.sname;
  5. }
8 s#2Zv  
2> 使用对象字面量创建对象 ,z+7rl  
复制代码
  1. var o = {
  2.     name: 'JChen___2',
  3.     getName: function(){
  4.         return this.name;
  5.     }
  6. }
7lYiufg  
但是这两个方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。 >^q7:x\  
S eTn]  
<2> 接下来看看几种创建对象的模式吧 -"Hy%wE  
1>工厂模式 0.}WZAYy~  
vRn"0Mzl8  
复制代码
  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___');
Nn]|#lLP  
pNIu;1M5a  
工厂模式也有一个缺点:就是没有解决对象识别的问题(即怎样知道一个对象的类型)。 {,`)  
oe*Y(T\G  
2> 构造函数模式 3(n+5~{e  
s2rwFj8 |  
复制代码
  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');
E|K~WO]>o  
jj$D6f/mOG  
构造函数模式也有一个缺点:就是每个方法都要在每个实例上创建一遍。 1o*eu&@  
当然我们可以用上面的两行注释掉了代码来屏蔽上面那个缺点。 pX~X{JTaL)  
但是……,我们又产生了一个新问题——全局变量。如果有很多方法,我们岂不是要定义很多个全局变量函数。这是个可怕的问题。 +P5\N,,7R  
v62M8r,Y  
3> 原型模式 Zj]jE%AT  
1) 普通方法 ]6BV`r]  
复制代码
  1. function create3(){}
  2. create3.prototype.name = 'JChen___5';
  3. create3.prototype.sayName = function(){
  4.     return this.name;
  5. };
  6. var p1 = new create3();
f;7I{Z\<  
.lt|$["  
2) 原型字面量方法——我姑且这么称吧 @W+m;4HH  
@P@j9yR  
复制代码
  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();
aIXN wnq  
U6/$CH<pe  
原型的缺点: #D2.RN  
1): 不能传参 <bbC &O\  
2): 共享了变量 Y_SB3 $])  
2#hfBJg@  
4> 构造+原型(模式) [')C]YQb=  
Y;dQLZ CC  
复制代码
  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');
cFF'ygJ/  
这种模式是目前使用最广泛、认同度最高的一种创建自定义类型的方法。 )] C"r_  
lK 0pr  
5> 动态原型模式 LeT OVgjA|  
}3DZ`8u  
复制代码
  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');
r;C BA'Z  
(aTpBXGr=  
这种方法确实也是十分完美的一种方法。 ZK p9k6  
#P)(/>nF  
6> 寄生构造函数模式 ?Tr\r1s]  
(S)jV 0  
复制代码
  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');
N}rc3d#  
^2 }p %j >  
注意那个return o。构造函数在不返回值的情况下,会返回新对象实例。而通过在构造函数的末尾加入return 语句,可以重写调用构造函数时返回的值。  aWTvowA  
这个种用法可以用在,假设我们想创建一个具有额外方法的特殊数组。由于不能直接修改Array的构造函数,因此可以使用这个模式。 7LrWS83  
Y4j%K~ls Y  
复制代码
  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
cI/Puh^3  
8^2E77s4U  
7>稳妥构造函数模式 V|`w/P9g4  
稳妥构造函数遵循与寄生构造函数类似的模式,但是有两点不同: og)f?4  
一是新创建对象的实现方法不引用this CjT]!D)s  
二是不使用new操作符调用构造函数。 l1uv]t <  
&(/QJ`*8  
复制代码
  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');
\F5d p  
^P~NE#p5  
二、JS继承的6种方法 7:Be.(a  
1> 原型链继承 :211T&B%A_  
原型链继承是通过创建Super的实例,并将该实例赋值给Sub.prototype来实现的。 + )lkH v$R  
实现的本质是:重写子类型的原型对象,代之以超类型的实例。 ,/Usyb,`  
oF {u  
复制代码
  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();
xI( t!aYp  
sRaTRL2  
注意:此时instance.constructor现在指向的是Super的,这是因为Sub.prototype指向了Super.prototype,而Super.prototype.constructor = Super。 _<m yM2z  
原型链的问题:类似于利用原型创建对象,原型共享的特性也是原型链继承的最大问题。 \l71Q/y6u`  
/&!4oBna  
2> 借用构造函数继承 M%"{OHj!o  
在解决原型中包含引用类型值所带来的问题的过程中,我们****始使用一种叫****借用构造函数的技术。 K! jMW  
这种技术的基本思想相当简单:在子类型构造函数的内部调用超类型构造函数。 c6~<vV'}  
这样一来,就会在新子类对象上执行超类函数中定义的所有对象初始化代码。结果,每个子类的实力都会有自己的超类中属性的副本了。 R!y`p:O C  
j&w4yY  
复制代码
  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');
"Kc1@EX=  
rPXy(d1<`S  
借助构造函数继承的问题: [iGL~RiXtn  
1): 方法都在构造函数中定义,无法复用。 (y!V0iy]  
2): 在超类型的原型中的方法对子类是不可见的。 y|2y! &o,!  
~Sc{\ZJl  
3> 组合继承(原型+借用构造) ?CSv;:  
组合继承指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。 #Zj3SfU~`  
组合继承的思路:使用原型链实现对方法和属性的继承,通过借用构造函数实现对实例属性的继承。 "?r_A*U  
? uu,w  
复制代码
  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. }
}zy h!  
L,_Z :\^  
组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为J****aScript中最常用的继承模式。 rPUk%S  
组合继承的问题:两次调用超类构造函数。 Pt\GVWi_t  
D V=xqC6}  
4> 原型式继承 =l+~}/7'Z  
原型式继承的思路:借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。 A40Q~X  
H*E4+3y  
复制代码
  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');
Mi:i1i cdn  
gH:+$FA  
原型式继承的问题:同原型链一样,他也有共享的劣势。 L.Tu7+M4  
%[WOQ.Sh  
5> 寄生式继承 'h3yxf}\  
寄生式继承的思路:创建一个仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再返回该对象 K_o[m!:jU  
:)DvZxHE@  
复制代码
  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);
~ U+W4%f8  
h 42dk(B  
寄生式继承的问题:像构造函数一样,由于不能****到函数的复用而降低效率。 +~\1g^h  
|{9&!=/qf  
6> 寄生组合式继承 ^k5#{?I  
寄生组合式继承:通过借用构造函数来借用属性,通过原型链的混成形式来继承方法。 l9vJ]   
其背后的思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们需要的无非就是超类型的一个副本而已。 6L,"gF<n  
Y[. f`Ei2  
复制代码
  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');
$8WeWmY  
:b"&Rc&s.  
****发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。 >TG#  
三、总结 T07 AH  
这就是J****aScript中的6种继承方式,如果大家能够画出每个继承的原型链关系图,那么继承就是小菜一碟了 u]MQ(@HHF  
了解了这些,你基本上对OOP有了一个入门,补充说明,以上内容均来自互联网,非本人原创。不过可能对于JS OOP重来没有接触过的同学看起来还是会觉得有些吃力,我最近也在整理这方面的资料并录制相关方向的课程,目录列下: St;@ZV  
复制代码
  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)
]6@6g>f?  
学完这套课程你能得到东西: gVI T6"/  
想学习JS的调试,性能优化,及一些优秀前端工具的使用 +@qIDUiF3  
对JS的应用有更深层次了解 0;tu}]jnN  
对JS OOP思想有一定程度的了解 o(eh.   
自己能动手写一个基于JS OOP的简单框架 d5#z\E??  
对于后继jquery,easyui,extjs等富客户端的学习打好基础 >9,:i)m_  
能用于J****a,PHP,.NET****发,移动****发工作中 =k##*%  
上述课程的录制正在进行中,欢迎大家多对课程提宝贵意见,以****内容,早日出来,以飨读者。 (kL(:P/  
另附:已经讲完的部分内容,大家可以下载下来看下,以加深对JS OOP的理解 z C 7b  
附下载: GsU.Lkf  
5. part1_c05_02_01_用定义函数的方式定义类 IubzHf  
6. part1_c05_02_02_使用new操作符获得一个类的实例 ccwz:7r  
7. part1_c05_02_03_动态添加、修改、****JS对象的属性和方法 6  jU ?~  
8. part1_c05_02_04_使用大括号({ })语法创建无类型对象 TTD#ovo'  
9. part1_c05_02_05_prototype原型对象 UL]zuW/  
10. part1_c05_03_01_初识j****ascript函数对象 *r|Zbxf(  
11. part1_c05_03_02_函数对象和其他内部对象的关系 Qq3>Xv <  
12. part1_c05_03_03_将函数作为参数传递 -FQc_k?VF  
13. part1_c05_03_04_传递给函数的隐含参数_arguments vQ8$C 3  
14. part1_c05_03_05_函数的apply、call方法的运用 ~T!D:2G  
15. part1_c05_03_06_深入认识J****aScript中的this指针 &Xh=bM'/%m  
链接: http://pan.baidu.com/s/1pJv09ib aj]pN,g@N  
密码:
本部分内容设定了隐藏,需要回复后才能看到
\ 0.!al0  
8^!ib/@v"  
全面深入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
最后登录: 2015-06-06
地下室(4楼)  发表于: 2014-05-11 18:05||

看看啊看卡看
级别: 终身会员

UID: 8195
精华: 0
发帖: 129
威望: 612 点
学点: 46 点
贡献: 0 点
好评: 0 点
学币: 0 个
注册时间: 2008-06-13
最后登录: 2015-06-06
下水道(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