Jun
11
[原]再谈JavaScript的用户自定义对象
前面写过一篇[原]JavaScript 的对象处理的日志,介绍了JavaScript中创建用户自定义对象的若干概念。不过,我觉得文中对原型对象、对象直接量、模拟命名空间等概念介绍不准确或不详细,有必要再做点补充。
一、Object 对象
在JavaScript中,Object对象是一个重要的本地对象,它是其他本地对象(如Array、Date、String等)的根对象,并提供了创建自定义对象的基础。
使用Object创建自定义对象后,可以为该对象添加属性和方法。这可见前面日志的介绍。
创建一个对象后,即可访问该对象的属性和方法:
1、Object对象的属性
prototype 属性返回对象类型原型的引用。
constructor 属性表示创建对象的函数。
2、Object对象的方法
HasOwnProperty 方法:判断对象是否具有某个特定的属性。
IsPrototypeOf 方法:判断对象是否为另一个对象的原型。
PropertyIsEnumerable 方法:判断给定属性能否用for-in语句进行枚举。
toString 方法:对于Object对象返回值为“[object Object]”。
valueOf 方法:与toString方法返回值相同。
Object对象的属性和方法将会被其他类覆盖。
二、改进构造函数
前面已经提到,可以通过创建构造函数,然后利用new运算符和该构造函数来创建新的对象实例。
无论直接利用Object对象的构造函数,还是定义自己的对象构造函数,都存在一个相同的问题,即创建新对象实例时会重复定义函数。(这样的说法明白吗?我觉得比之前的提法要更容易理解。)
为了解决这个问题,可以通过对象的原型对构造函数加以改进,利用以下方式来定义构造函数:
在改进的构造函数中,通过检查和设置_initialized属性的值可以保证为类添加方法时不会重复定义函数。这样,创建新对象实例时,因原型对象的方法可被该实例使用,而且不需要重复定义函数,节省了资源。
三、对象直接量
使用对象直接量时,应通过花括号把属性和属性值括起来,属性名和属性值用冒号分割,属性—值对用逗号分隔。
例如:
在JavaScript中,对象引用也可以作为函数的参数使用,通常有以下两种处理方式:
相比之下,后一种方式显然更为简便,因为既不需要定义构造函数,也不需要显式创建对象实例。
三、模拟命名空间
在面向对象语言中,通常使用命名空间来组织类,以避免名称冲突的问题。在JavaScript中,可以通过对象来模拟命名空间。创建一个JavaScript库时,可以将对象定义包装在命名空间内,而不需要定义全局函数和类。
使用对象模拟命名空间时,首先创建一个空对象作为命名空间,然后在此命名空间中定义构造函数。
以下是模拟命名空间的代码:
当然,根据需要,还可以创建嵌套的命名空间,然后通过“.”号调用即可。
一、Object 对象
在JavaScript中,Object对象是一个重要的本地对象,它是其他本地对象(如Array、Date、String等)的根对象,并提供了创建自定义对象的基础。
var object=new Object();
使用Object创建自定义对象后,可以为该对象添加属性和方法。这可见前面日志的介绍。
创建一个对象后,即可访问该对象的属性和方法:
object.{property|method(argList)}
1、Object对象的属性
prototype 属性返回对象类型原型的引用。
constructor 属性表示创建对象的函数。
2、Object对象的方法
HasOwnProperty 方法:判断对象是否具有某个特定的属性。
IsPrototypeOf 方法:判断对象是否为另一个对象的原型。
PropertyIsEnumerable 方法:判断给定属性能否用for-in语句进行枚举。
toString 方法:对于Object对象返回值为“[object Object]”。
valueOf 方法:与toString方法返回值相同。
Object对象的属性和方法将会被其他类覆盖。
二、改进构造函数
前面已经提到,可以通过创建构造函数,然后利用new运算符和该构造函数来创建新的对象实例。
无论直接利用Object对象的构造函数,还是定义自己的对象构造函数,都存在一个相同的问题,即创建新对象实例时会重复定义函数。(这样的说法明白吗?我觉得比之前的提法要更容易理解。)
为了解决这个问题,可以通过对象的原型对构造函数加以改进,利用以下方式来定义构造函数:
function constructorName(argList) {
this.propertyName=value; //设置对象的属性
if (typeof constructorName._initialized=="undefined") {
constructorName.prototype.methodName=function(argList) {
body
}
constructorName._initialized=true;
}
}
this.propertyName=value; //设置对象的属性
if (typeof constructorName._initialized=="undefined") {
constructorName.prototype.methodName=function(argList) {
body
}
constructorName._initialized=true;
}
}
在改进的构造函数中,通过检查和设置_initialized属性的值可以保证为类添加方法时不会重复定义函数。这样,创建新对象实例时,因原型对象的方法可被该实例使用,而且不需要重复定义函数,节省了资源。
三、对象直接量
使用对象直接量时,应通过花括号把属性和属性值括起来,属性名和属性值用冒号分割,属性—值对用逗号分隔。
例如:
var object={
"propertyName":"value",
"methodName":function(argList) {statements}
};
"propertyName":"value",
"methodName":function(argList) {statements}
};
在JavaScript中,对象引用也可以作为函数的参数使用,通常有以下两种处理方式:
引用
1、要把一个对象传递给函数,可以通过基于构造函数创建一个对象实例并将该对象的引用存储在一个变量中,然后把该变量作为实际参数用在函数调用中;
2、在函数调用中使用对象直接量作为实际参数。
2、在函数调用中使用对象直接量作为实际参数。
相比之下,后一种方式显然更为简便,因为既不需要定义构造函数,也不需要显式创建对象实例。
三、模拟命名空间
在面向对象语言中,通常使用命名空间来组织类,以避免名称冲突的问题。在JavaScript中,可以通过对象来模拟命名空间。创建一个JavaScript库时,可以将对象定义包装在命名空间内,而不需要定义全局函数和类。
使用对象模拟命名空间时,首先创建一个空对象作为命名空间,然后在此命名空间中定义构造函数。
以下是模拟命名空间的代码:
var MyNS={};
MyNS.constructorName=function(argList) { //在命名空间中定义一个构造函数
statments; //在此处编写代码,为对象添加属性和方法
};
var object=new MyNS.constructorName("argList");
MyNS.constructorName=function(argList) { //在命名空间中定义一个构造函数
statments; //在此处编写代码,为对象添加属性和方法
};
var object=new MyNS.constructorName("argList");
当然,根据需要,还可以创建嵌套的命名空间,然后通过“.”号调用即可。