js创建对象

  因为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,Matt
alert(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();//red oCar2.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出的对象也都带有该属性,这样所有函数都只创建一次,每个对象都有自己的对象属性实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值