JavaScript 中的 OOP。






3.76/5 (15投票s)
2004年9月14日
5分钟阅读

53079
JavaScript 编程语言的 OOP 方面。
引言
Sergey Zavadski 的文章介绍了 JavaScript 编程语言的对象模型,并展示了 JavaScript 中 OOP(面向对象编程)的常见实践。
JavaScript 的简洁性。
事实证明,JavaScript 是最容易学习和使用的编程语言之一。 一小段代码(实际上是一行)可以执行各种操作,例如创建窗口或更改状态栏中的文本。 灵活性、简短的学习曲线以及 JavaScript 不是“强类型”语言的事实,解释了 JavaScript 在 Web 开发者社区中的极高人气,他们选择这种语言作为为静态 HTML 页面提供动态吸引人内容的语言。
强大的工具
然而,尽管 JavaScript 表面上很简单,但当遵循 DOM 规范时,它实际上是一个非常先进且功能强大的工具,为创建复杂的(客户端)解决方案(如菜单、树、网格等)提供了所有必需的功能。这些可能性实际上反映了 JavaScript 在图层操作方面的强大功能。 这并非最重要的原因,而是 JavaScript 编程语言的 OOP 结构,它被设计和实现为一种面向对象的语言!
对象模型
JavaScript 对象是具有属性的实体,这些属性可以是其他对象或变量。 例如,我们有一个 Country_Italy
对象。 我们可以像这样为该对象的属性赋值
Country_Italy.Name=”Italy”;
Country_Italy.Capital=”Rome”;
Country_Italy.Area=301000;
但是,‘Country_Italy
’ 对象本身也可以是另一个对象的属性
Europe.MostBeautifulCountry= Country_Italy;
JavaScript 带有像 Window
、Math
、String
等内置对象的库。 但使该语言真正灵活的是创建自定义对象的能力。 在 JavaScript 中创建自定义对象有两种可能的方法。 第一种是使用直接初始化。 这种情况下代码可能看起来像这样
Country={Name:”France”,Capital:”Paris”,Government:{President:”Jacques Chirac”}};
我们创建了具有‘Name
’、‘Capital
’ 和‘Government
’ 属性的 Country
对象,并且‘Government
’ 属性是一个具有自己属性列表的对象。 我们还用初始值初始化了这些属性。 所有这些都在一个字符串中完成。 以下构造创建并初始化了空对象
Country={};
在 JavaScript 中创建对象的另一种方法是定义特殊函数构造函数,并使用‘new
’运算符初始化对象。 例如
function Country(Name,Capital,Population){
this.Name=Name;
this.Capital=Capital;
this.Population=Population;
}
‘Country
’函数是构造函数。 现在,要使用这个定义的构造函数创建对象,我们使用 new
运算符
Country_Italy=new Country(“Italy”,”Rome”,301000);
就像在前面的示例中一样,属性可以是对象本身
function Government(President){
this.President=President;
}
function Country(Name,Capital,Government){
this.Name=Name;
this.Capital=Capital;
this.Government=Government;
}
Government_France=new Government(“Jacques Chirac”);
Country_France=new Country(“France”,”Paris”,Government_France);
JavaScript 中完全实现的 OOP 的另一个优点是对象可以拥有方法(而不仅仅是属性)。 方法是在对象范围内描述的函数,通常操作对象属性。 方法的描述方式与属性类似
function describeCountry(){
var desc=”Name: ”+this.Name+” Capital: ”+
this.Capital+” Population: “+this.Population;
alert(desc);
}
在上面的定义中,this
运算符提供了对描述的方法所属对象的访问。
Country_Italy.describeCountry=describeCountry;
下面的构造完全重复了上面的构造
Country_Italy.describeCountry=function(){
var desc=”Name: ”+this.Name+” Capital: ”+
this.Capital+” Population: “+this.Population;
alert(desc);
}
构造
Country_Italy.describeCountry();
调用‘Country_Italy
’对象的‘describeCountry
’方法。
基于原型的面向对象语言
与某些其他流行的 OO 语言(Java、C++)不同,后者的对象模型基于类,JavaScript 的对象模型基于原型。 这两种方法的主要区别在于,在基于原型的语言中,类和类实例实体之间没有区别——你只处理对象。
原型(可以看作是定义初始对象属性值如何分配的模板)是任何用原型运算符声明的对象。 该对象可以是任何新创建对象的父对象,这就是 JavaScript 支持继承的方式——OOP 语言的重要特征。 让我们看看我们的 Country
对象
function Country(Name,Capital,Population){
this.Name=Name;
this.Capital=Capital;
this.Population=Population;
}
现在,让我们声明‘Cn
’——‘Country
’对象的原型
Cn=Country.prototype;
Cn.describeCountry=function(){
var desc=”Name: ”+this.Name+” Capital: ”+
this.Capital+” Population: “+this.Population;
alert(desc);
}
现在,我们可以用只有两行代码的方式在任何‘Country
’的后代中调用‘describeCountry
’方法
Country_Italy=new Country(“Italy”,”Rome”,301000);
Country_Italy.describeCountry();
使用这种方法,我们可以在原型中定义任意数量的方法和属性。 在原型中定义方法和属性,而不是直接为每个对象定义它们,有很多优点
- 每次设计对象时,您不必定义所有必需的方法或属性。 您在原型中定义所有必需的方法和属性,然后您所要做的就是创建对象。
- 使您的代码更安全,因为您可以将所有对象定义保留在一个单独的文件中。
- 使您的代码更易于阅读。
继承
JavaScript 还支持继承机制,这是 OOP 的基石。
为了展示 JavaScript 继承机制的简便性,让我们回顾一下我们已经定义的两个对象:“Country
”和“Government
”,以及一个新对象“Parliament
”。
这些对象的构造函数将是这样的
function Country(Name,Capital,Population){
this.Name=Name;
this.Capital=Capital;
this.Population=Population;
}
function Government(President){
this.President=President;
}
function Parliament(Speaker){
this.Speaker=Speaker;
}
看看‘Country
’对象原型。
Cn=Country.prototype;
Cn.describeCountry=function(){
var desc=”Name: ”+this.Name+” Capital: ”+
this.Capital+” Population: “+this.Population;
alert(desc);
}
以下构造定义了‘Country
’为‘Government
’原型(‘Government
’继承自‘Country
’)
Government.prototype=new Country("France","Paris",59330000);
当创建‘Government
’对象时,它会继承‘Country
’的所有方法和属性。 换句话说,虽然‘describeCountry()
’方法未为‘Government
’对象定义,但它可用,因为‘Country
’对象被定义为‘Government
’原型。
Government_France=new Government("Jacques Chirac");
Government_France.describeCountry();
还可以为‘Government_France
’对象定义新方法
Government_France.describeGovernment=function(){
alert(“President: ”+this.President);
}
让我们完成‘Parliament
’对象定义。
Parliament.prototype=new Country("France","Paris",59330000);
Pn=Parliament.prototype;
Pn.describeParliament=function(){
alert("Speaker: "+this.Speaker);
}
Parliament_France=new Parliament("Jean-Louis Debre");
如您所见,原型也可以为继承的对象修改。
上面的例子展示了 JavaScript OOP 模型的优雅,它使这种易于学习的语言能够执行各种复杂的实际编程任务。
实际示例
在我们的公司开发 CodeThat.Com 的 Web 控件集时,就使用了这种 OOP 方法。 例如,‘CodeThatCalendar
’只不过是一个声明为
function CodeThatCalendar(def) {
this.def = def;
this.links = {};
this.styles = {};
this.hideifr = true;
if (typeof(this.def.img_path)!="undefined") {
if (this.def.img_path.lastIndexOf("\/")!=this.def.img_path.length-1)
this.def.img_path=this.def.img_path+"\/";
}
if (typeof(this.def.template_path)!="undefined") {
if (this.def.template_path.lastIndexOf("/")!=
this.def.template_path.length-1)
this.def.template_path=this.def.template_path+"/";
if (this.def.template_path.indexOf("\/")!=0)
if (typeof(this.def.img_path)!="undefined" &&
this.def.img_path.indexOf("\/")!=0) {
s=this.def.template_path;
a=s.split("/");
a.length=a.length-1;
t="";
for (i=0; i<a.length; i++){
t=t+"../";
}
this.img_path=t+this.def.img_path;
}
}
};
var CTc = CodeThatCalendar.prototype;
CTc.hide = function()
{
…
}
CTc.create = function(d,ctl) {
…
}
控件的各种方法使用图层,为控件提供精美的外观和感觉,并使用户能够执行日历应执行的各种操作。 例如,下面的函数将 HTML 表单控件的值设置为用户选择的日期。 每次用户单击日历日期时都会执行此操作。
function CodeThatSetDay(c,f,d,m,y,i,ifr) {
var doc;
var w = window.opener||this.parent;
if(w&&!i)
doc = w.document;
else
doc = document;
var e = CodeThatFind(doc,c);
if(Def(e))
{
e.value=CodeThatDateFormat(f,d,m,y);
if(e.fireEvent) e.fireEvent("onchange");
else {
if(e.onchange) e.onchange();
}
}
if(w&&!i)
{
if(Def(w) && Def(ifr))
{
var iframe = CodeThatFind(doc,ifr);
if(Def(iframe))
iframe.style.visibility = 'hidden';
if(ua.opera6)
{
var d = CodeThatFind(doc,"calendar_div");
if(Def(d))
d.style.visibility='hidden';
}
}
else
{
window.close();
}
}
};
(CodeThatCalendar
函数的示例不完全可用。此处列出仅供说明之用)。如您所见,JavaScript 确实是一种强大且用户友好的编程语言,它具有许多功能,有助于创建真正复杂且有趣的解决方案。由于大多数现代浏览器都支持 DOM 模型,因此您可以确信您的解决方案将对大多数用户可用。当然,JavaScript 中还有很多东西需要学习:事件、DOM、图层以及跨浏览器兼容性有时也不那么透明,但这又是另一篇故事或……几篇故事。