首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议102:使用享元类

关灯直达底部

享元类就是类的类型,即创建类型的类。享元类与类的关系正如类与对象的关系一样,是一种创建型的泛化关系。享元类能够接受类作为参数,即享元类操作的对象是类,而不是具体的数据。一般享元类返回的是类,而不是具体的数据。下面的示例就是一个简单的享元类,它包含了一个返回的类。


function O(x){//享元类

return function{//类

this.x=x;

this.get=function{

alert(this.x);

}

}

}

var o=new O(1);

var f=new o;

f.get;//调用返回类的方法get,返回1


从上面的示例可以看到,享元类与普通函数没有什么两样,不过它的返回值是类,而不是具体数值。实际上,JavaScript核心对象Function就是一个享元类,虽然说它没有返回值,但是我们可以通过字符串的形式创建返回类。例如:


var O=new Function("this.x=1;this.y=2")//实例化之后返回的是类

var o=new O;//实例化返回类

alert(o.x);//调用实例的属性值,返回1


上面的示例演示了简单的函数中包含一个返回类结构,当然享元类并非如此简单。下面再演示一个比较复杂的示例,在这个享元类中参数值包含类类型,返回值也是类类型。

首先,定义一个普通类,作为一个参数值准备传递给享元类。


function F(x,y){

this.x=x;

this.y=y;

}

F.prototype.add=function{

alert(this.x+this.y);

}


然后,定义一个享元类,该函数类包含3个参数,其中第一个参数为类类型,第二个和第三个参数是值类型数据。


function O(o,x,y){

this.say=function{

alert("享元类");

}

return function{

this.say=function{

alert("返回类");

}

var a=new o(x,y);//实例化参数类

for(var i in a){//通过实例继承法,继承参数类给返回类

this[i]=a[i];//此时this关键字只返回类的当前对象

}

}

}


最后,使用new运算符调用享元类,第一个参数值为上文定义的类F,第二个和第三个参数为普通数值,返回的类赋值给变量A,则A就变成了一个类结构。此时不能够通过A来读取享元类的本地方法say。


var A=new O(F,1,2);

var B=new A;

A.say;//如果直接调用享元类的本地方法,将提示编译错误


但可以通过实例化后的B对象来访问参数类F中的成员,以及返回类内部定义的本地属性。


B.say;//字符串"返回类"

B.add;//数值3

alert(B.x);//数值1

alert(B.y);//数值2


注意,当一个类有返回值时,如果是值类型数据,则可以访问类的成员,也可以获取返回值。


function F{

this.x=1;

return 2;

}

var f=new F;

alert(f.x);//1

alert(F);//2


如果类返回的是引用类型或函数体,则类的成员将不可访问,它们将成为闭包结构内的私有数据,不再对外开放。


function F{

this.x=1;

return function{

return this.x;

};

}

F.prototype.y=function{

alert(3);

}

var f=new F;

alert(f.x);//访问本地属性x失败,返回undefined

alert(F);//调用返回的函数,返回1,说明它可以访问本地属性x

alert(f.y);//提示编译错误,没有这个成员