转自:http://gaojiewyh.iteye.com/blog/1931968 (原文更易阅读)

在面向对象的Javascript编程中,希望代码优雅有高效是非常重要的。javascript中不存在类的概念,只有对象。要想把Javascript代码写的像java 或者C++一样优雅,就得考虑如何去实现,同时也要考虑性能和高效。定义javascript对象的方式有很多,继承的方式也很多。通过不断地实践,推荐如下的方法:

1.Javascript对象的定义采用混合方式【构造函数 +原型方式(prototype)】

(1)通过构造函数方式定义对象的所有非函数属性

(2)用原型方式定义对象的函数属性

 

采用这种方式,所有的属性都是单一对象私有的,而方法则是所有对象公有的,对象之间的属性不相互干扰,各个对象间共享同一个方法。

 

Js代码  收藏代码
  1. //使用原型+构造函数方式来定义对象  
  2. //构造函数定义对象的非函数属性<strong>  
  3. function Person()  
  4. {  
  5.         this.username = new Array();  
  6.         this.password = "123";  
  7. }  
  8.   
  9. </strong>//通过原型方式定义对象的函数<strong>  
  10. Person.prototype.getInfo = function()  
  11. {  
  12.         alert(this.username+","+this.password);  
  13. };  
  14.   
  15. var p = new Person();  
  16. var p2 = new Person();  
  17. p.username.push("zhangsan");  
  18. p2.username.push("lisi");  
  19. p.getInfo();  
  20. p2.getInfo();  
  21. </strong>  

 在现实的开发过程中,我们可能希望开发的各个类(实质是对象)能像java程序中放到一个包中统一管理,统一使用,而各个对象相互独立,同时避免对象重名等等因素,我们需要给每个类有个作用域,此时我们采用将对象放到自定匿名函数的方式来解决,这一点和jQuery开发插件的有点类似。代码如下:

 

 

Js代码  收藏代码
  1. /** 
  2.  * @author jasson 
  3.  * @include common.js 
  4.  */  
  5.    
  6. //对象存在就等于对象,对象不存在就创建{}  
  7. var JassonChart = JassonChart || {};  
  8. (function(){  
  9.     //构造函数定义对象的非函数属性  
  10.     function Person()  
  11.     {  
  12.         this.username = new Array();  
  13.         this.password = "123";  
  14.     }  
  15.       
  16.     //通过原型方式定义对象的函数  
  17.     Person.prototype.getInfo = function()  
  18.     {  
  19.             alert(this.username+","+this.password);  
  20.     };  
  21.     //将该类放到JassonChart中,类似java中的包,或者C++中的  
  22.     JassonChart.Person= Person;  
  23. }());  
  24. //调用该类库中的Person类  
  25. var p = new JassonChart.Person();  

      这样我们可以定义多个类,每个类都采用如上的方式实现,这样各个类相互都有作用域,非常规范。对于我们要用到的一些工具类,我们可以采用简单的对象进行定义,代码如下

Java代码  收藏代码
  1. /**  
  2. * @author jasson  
  3. */   
  4. var JassonChart = JassonChart || {};   
  5.   
  6. JassonChart .util = {   
  7. constants : {   
  8. WIDTH : 'width',   
  9. HEIGHT : 'height',   
  10. SVG : 'SVG',   
  11. CANVAS : 'CANVAS',   
  12. G : 'G'//svg element   
  13. STRING : 'string'   
  14. },   
  15. distance : function(a, b) {   
  16. var dx = a.x - b.x;   
  17. var dy = a.y - b.y;   
  18. return Math.sqrt(dx * dx + dy * dy);   
  19. }  
  20. };   

 2.Javascript对象的继承采用如下几种方式

2.1 Javascript对象的继承采用混合方式【构造函数 +原型方式(prototype)】

在JavaScript中最好的方式就是用混合方式实现对象间的继承。和定义对象一样,我们可以将属性和方法用不同的方式定义,用call或apply方式定义继承对象的属性,利用原型链的方式实现方法的继承。如下代码所示:

Java代码  收藏代码
  1. //使用混合的方式实现对象的继承   
  2. function Parent(hello)   
  3. {   
  4.     this.hello = hello;//定义父类的属性   
  5. }   
  6. Parent.prototype.sayHello = function()//定义父类的方法   
  7. {   
  8.     alert(this.hello);   
  9. }   
  10. function Child(hello,world)   
  11. {   
  12.     Parent.call(this,hello);//继承父类的属性   
  13.     //or Parent.apply(this,arguments);//继承父类的属性   
  14.     this.world = world;   
  15. }   
  16. Child.prototype = new Parent();//继承父类的方法   
  17. Child.prototype.sayWorld = function()   
  18. {   
  19.     alert(this.world);   
  20. }   
  21. var child = new Child("hello","world");   
  22. child.sayHello();   
  23. child.sayWorld();   

 2.2 深度拷贝方法

所谓"深拷贝",就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用"浅拷贝"就行了。

Java代码  收藏代码
  1. function deepCopy(p, c) {   
  2.     var c = c || {};  
  3.     for (var i in p) {   
  4.     if (typeof p[i] === 'object') {   
  5.         c[i] = (p[i].constructor === Array) ? [] : {};  
  6. deepCopy(p[i], c[i]);  
  7. else {  
  8. c[i] = p[i];  
  9. }  
  10. }  
  11. return c;  
  12. }  

 使用的时候这样写:

var Doctor = deepCopy(Chinese);

现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性:

Chinese.birthPlaces = ['北京','上海','香港'];

Doctor.birthPlaces.push('厦门');

这时,父对象就不会受到影响了。

alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门

alert(Chinese.birthPlaces); //北京, 上海, 香港

目前,jQuery库使用的就是这种继承方法。



本文转载:CSDN博客