众所周知javascript不是面向对象的脚本语言,而是基于对象的,简言之,就是 javascript没有类
在此我要介绍的是如何用 javascript的函数(function)来模拟构造类(class)
在javascript中定义一个函数是如此简单
function funName()
{
.....
}
下述代码复制可运行
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//构造一个人类,包含姓名、姓别、年龄属性
Person = function()
{
//定义pulic属性,以this做前缀
this.name = null;
//定义private属性,以var方式定义
//通常为区分public和private,private型以"_"开头
var _sex = null;
//定义public方法
this.setName = function( p_name )
{
//虽然name是public变量,在类内部引用public变量必须以this做前缀
this.name = p_name;
}
this.getName = function()
{
return this.name;
}
//定义private方法,私有方法不以this指针做前缀
function setSex( p_sex )
{
_sex = p_sex;
}
function getSex()
{
return _sex;
}
//toString()方法重写,显然是公有的方法
this.toString = function()
{
return this.name + " from toString().";
}
//必须返回
return this;
}
/**********************************************************************
注:通过以上类的定义,可看出公有的属性和方法都以this指针做前缀
私有的属性和方法与javascipt定义变量和函数完全一致
**********************************************************************///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//类的使用
var person1 = new Person();
//调用public属性
alert("call public property 'name' before 'setName()':" + person1.name);
//调用public方法
person1.setName("testName");
alert("call public method 'getName()' after 'setName()':" + person1.getName());
//调用private属性,提示undefined
//alert(person._sex);
//调用private方法,弹出脚本错误:对象不支持此属性或方法
//alert(person.getSex());
/************************************************************************
注:为什么调用private属性和方法,提示的错误不同呢?
其实,通过类的实例调用private属性,并非错误,而是javascript类的扩展
而通过类的实例调用private方法,则是错误的
private属性和方法是不允许直接调用的
上述Person1._sex实质上并非调用的私有变量完全是一个新的变量,
因为在类之外是看不到私有属性的,这就是 对类属性 的扩展。
但是这种扩展只是该实例的扩展,也就是只允许person1实例访问
对一个新的Person实例person2,没有权限访问扩展变量
************************************************************************/
person1.age = 30;
alert(person1.age);
//新的实例调用person1的扩展属性,提示undefined
//var person2 = new Person();
//alert(person2.age);
//类方法的扩展跟属性的扩展规则是相同的
person1.method1 = function()
{
return "'method1()' is static method";
}
alert(person1.method1());
//新的实例调用Person的扩展方法,提示脚本错误:对象不支持此属性或方法
//alert(person2.method1());
//调用toString()
alert("call public 'toString()':"+person1);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//定义static属性,静态的属性不能在类的内部定义
//要在定义完类之后,在类外以(类名.)形式做前缀
Person.career = "'career' is static property";
alert(Person.career);
//定义static方法,静态的方法不能在类的内部定义
//要在定义完类之后,在类外以(类名.)形式做前缀
Person.method2 = function()
{
return "'method2()' is static method";
}
alert(Person.method2());
//静态变量和方法只能通过类名调用,不能用实例调用
//var person2 = new Person();
//alert(person2.method());
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//最后要讲的是,类的构造方法
//其实javascript本不存在类的概念,上述的类完全是我们用function模拟而来
//因此对javascript而言,类自身即是其构造函数如下所述
//Person = function(arg1, arg2, ...)
//var person = new Person(ar1, arg2, ...);//-->
//////////////////////////////////////////////////////////////////////////////
//构造一个人类,包含姓名、姓别、年龄属性
Person = function()
{
//定义pulic属性,以this做前缀
this.name = null;
//定义private属性,以var方式定义
//通常为区分public和private,private型以"_"开头
var _sex = null;
//定义public方法
this.setName = function( p_name )
{
//虽然name是public变量,在类内部引用public变量必须以this做前缀
this.name = p_name;
}
this.getName = function()
{
return this.name;
}
//定义private方法,私有方法不以this指针做前缀
function setSex( p_sex )
{
_sex = p_sex;
}
function getSex()
{
return _sex;
}
//toString()方法重写,显然是公有的方法
this.toString = function()
{
return this.name + " from toString().";
}
//必须返回
return this;
}
/**********************************************************************
注:通过以上类的定义,可看出公有的属性和方法都以this指针做前缀
私有的属性和方法与javascipt定义变量和函数完全一致
**********************************************************************///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//类的使用
var person1 = new Person();
//调用public属性
alert("call public property 'name' before 'setName()':" + person1.name);
//调用public方法
person1.setName("testName");
alert("call public method 'getName()' after 'setName()':" + person1.getName());
//调用private属性,提示undefined
//alert(person._sex);
//调用private方法,弹出脚本错误:对象不支持此属性或方法
//alert(person.getSex());
/************************************************************************
注:为什么调用private属性和方法,提示的错误不同呢?
其实,通过类的实例调用private属性,并非错误,而是javascript类的扩展
而通过类的实例调用private方法,则是错误的
private属性和方法是不允许直接调用的
上述Person1._sex实质上并非调用的私有变量完全是一个新的变量,
因为在类之外是看不到私有属性的,这就是 对类属性 的扩展。
但是这种扩展只是该实例的扩展,也就是只允许person1实例访问
对一个新的Person实例person2,没有权限访问扩展变量
************************************************************************/
person1.age = 30;
alert(person1.age);
//新的实例调用person1的扩展属性,提示undefined
//var person2 = new Person();
//alert(person2.age);
//类方法的扩展跟属性的扩展规则是相同的
person1.method1 = function()
{
return "'method1()' is static method";
}
alert(person1.method1());
//新的实例调用Person的扩展方法,提示脚本错误:对象不支持此属性或方法
//alert(person2.method1());
//调用toString()
alert("call public 'toString()':"+person1);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//定义static属性,静态的属性不能在类的内部定义
//要在定义完类之后,在类外以(类名.)形式做前缀
Person.career = "'career' is static property";
alert(Person.career);
//定义static方法,静态的方法不能在类的内部定义
//要在定义完类之后,在类外以(类名.)形式做前缀
Person.method2 = function()
{
return "'method2()' is static method";
}
alert(Person.method2());
//静态变量和方法只能通过类名调用,不能用实例调用
//var person2 = new Person();
//alert(person2.method());
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//最后要讲的是,类的构造方法
//其实javascript本不存在类的概念,上述的类完全是我们用function模拟而来
//因此对javascript而言,类自身即是其构造函数如下所述
//Person = function(arg1, arg2, ...)
//var person = new Person(ar1, arg2, ...);//-->