js创建对象

来源:互联网 发布:软件系统安全 考试题 编辑:程序博客网 时间:2024/05/18 22:08

  因为js在语法上跟C#有一定的区别,同样在创建对象上也有体现,这里先列出最常用的创建对象的方法,然后再分析一下其他的创建对象的方法的一些弊端。

  使用构造函数和原型方式创建对象:使用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法),这样可以保证,只创建一个函数实例,没有内存浪费。

function Car(sColor,iDoors,iMpg){this.color=sColor;this.doors=iDoors;this.mpg=iMpg;this.drivers=new Array("Mike","Sue");}//只创建了showColor()函数的一个实例,所以没有内存浪费Car.prototype.showColor=function(){alert(this.color);};

或者使用动态原型方法:增加一个_initialized标志,保证在prototype对象上仅定义一次showColor()函数。
function Car(sColor,iDoors,iMpg){this.color=sColor;this.doors=iDoors;this.mpg=iMpg;this.drivers= new Array("Mike","Sue");if(typeof Car._initialized == "undefined"){Car.prototype.showColor = function(){alert(this.color);};Car._initialized = true;}}

调用:

var oCar1= new Car("red",4,23);var oCar2= new Car("blue",3,25);oCar1.drivers.push("Matt");alert(oCar1.drivers);//Mike,Sue,Mattalert(oCar2.drivers);//Mike,Sue

 

 其他不良的定义类的方法:

var oCar = new Object;//对象的属性可以在对象创建后动态定义。oCar.color="red";oCar.doors=4;oCar.mpg=23;//方法也是属性,它是指向函数的指针oCar.showColor=function(){ alert(this.color);};

  这种方法有个问题:在使用的时候可能需要创建多个car实例,造成内存浪费
为解决这个问题,可以使用创建特定类型对象的工厂函数:

function createCar(){var oTempCar = new Object;oTempCar.color="red";oTempCar.doors=4;oTempCar.mpg=23;oTempCar.showColor=function(){alert(this.color);};return oTempCar;}var oCar1 = createCar();var oCar2 = createCar();

  这种方法一个最大的弊端是实例的属性都是一样的,不能修改,可以做如下修改:

function createCar(sColor,iDoor,iMpg){ var oTempCar = new Object;//这里没有括号 oTempCar.color=sColor; oTempCar.door=iDoor; oTempCar.mpg=iMpg; oTempCar.showColor=function(){  alert(this.color); }; return oTempCar; }var oCar1= createCar("red",4,23);var oCar2=createCar("blue",3,25);

oCar1.showColor();//redoCar2.showColor();//blue

  这种做法并不是理想的做法,原因:看起来不像使用带有构造函数的new的运算符那么正规;功能上用这种方式必须创建对象的方法,每次调用函数createCar()的时候,都要创建新函数showColor(),意味着每个对象都有自己的showColor()版本,事实上,每个对象都共享了同一个函数。

  为解决这个问题,可以在工厂函数外定义对象的方法,然后通过属性指向该方法:

function showColor(){ alert(this.color);}

function createCar(sColor,iDoors,iMpg){ var oTempCar= new Object; oTempCar.color=sColor; oTempCar.doors=iDoors; oTempCar.mpg=iMpg; oTempCar.showColor=showColor;//这里的函数也没有括号

 return oTempCar;

}

var oCar1= createCar("red",3,23);var oCar2= carteCar("blue",3,25);

oCar1.showColor();oCar2.showColor();

  在函数createCar()前定义了函数showColor(),在createCar()内部,赋予一个指向已经存在的showColor()函数的指针,这样解决了重复创建对象的问题。但是这样不符合一般的new对象的习惯。

  为解决这个问题,不在内部使用Object对象:

function Car(sColor,iDoors,iMpg){this.color=sColor;this.doors=iDoors;this.mpg=iMpg;this.showColor=function(){alert(this.color);};}var oCar1= new Car("red",4,23);var oCar2= new Car("blue",3,35);

  这里使用this关键字,使用new运算符调用构造函数时,在执行第一行代码前,先创建一个对象,只有this才能访问该对象。然后可以直接赋予this属性,默认情况下是构造函数的返回值,而不必明确使用return运算符。

  这里仍然会重复生成函数,为每个对象都创建独立的函数版本。所以,我们仍然可以用外部函数重写构造函数。
这里使用对象的prototype属性:

//用空的构造函数设置类名,所有的属性和方法都直接赋予prototype属性function Car(){}Car.prototype.color="red";Car.prototype.doors=4;Car.prototype.mpg=23;Car.prototype.showColor=function(){alert(this.color);};//调用new Car()时,原型的所有属性都被立即赋予要创建的对象,也就是说所有Car实例存放的都是指向showColor()函数的指针。var oCar1= new Car();var oCar2= new Car();//使用了prototype可以使用instanceof运算符检查给定变量指向的对象的类型alert(oCar1 instanceof Car);//true

 

综上:

1、我们可以看到在js中没有显示的使Class关键字来说明创建对象。

2、在js中,函数既是对象,另外直接使用{}可以表示一个对象.

3、在类(函数)内部调用了new运算符后,在调用(实例化)时,将忽略new运算符,但是为了OO,我们可以写上new关键字。

4、对象的属性可以在对象创建后动态定义。

5、方法也是属性,它是指向函数的指针。

6、使用this关键字,使用new运算符调用构造函数时,在执行相关代码前,先创建一个对象,且只有this才能访问该对象。

7、使用了prototype就可以使用instanceof运算符检查给定变量指向的对象的类型。

8、每个构造函数都有一个prototype属性,可用于定义方法。

9、每个本地对象也有用方法完全相同的prototype属性,本地对象继承的是Object对象,如果想给本地对象添加、修改属性,可以在Object对象的prototype属性上操作。

10、原型中添加的属性是所有的新对象的指针的引用源,在原型中添加了后,其他new出的对象也都带有该属性,这样所有函数都只创建一次,每个对象都有自己的对象属性实例。

原创粉丝点击