它的可人之处可一一数来:
用JS你可以进行面向对象的开发了(大语言有的,它也有了)。
1、自定义类(系统内置的Date、Array、String等也是类)。
例如:
//定义类
function Student()
{
//定义属性(私有)
var addr = "";
//定义属性(公有)
this.age = 20;
this.name = "HOTEL";
//为类注册方法 一
this.addAge = addAge;
//为类注册方法 二
this.setName = function(na)
{
this.name = na;
}
this.setAddr = function(address)
{
addr = address;
}
this.getAddr = function()
{
return addr;
}
}
function addAge(ag)
{
this.age += ag;
}
var s1 = new Student();
s1.addAge(3);
s1.setName("李小龙");
s1.setAddr("莲湖区1号");
document.write("name:"+s1.name +"<BR><BR> age:"+s1.age+"<BR><BR> address: "+s1.getAddr());
既然这么多老兄们也关注JS这个小宠,我就再继续谈谈怎么将面向对象做得再像点吧。
2.我们来看看怎么实现继承,方法很多,但我感觉用类(实际上是函数)本身的apply和Call实现比较正宗。
//-----------------定义区----------------------------------------------
//基类
function person(name,age)
{
this.name = name;
this.age = age;
this.describe = function()
{
return "Name: " + this.name + "/nAge:" + this.age ;
}
}
//派生类
function employee(name,age,work_no)
{
//初始化基类
var baseArgs = [name,age];
//apply和call仅仅是调用方法不一样.
//person.apply(this,baseArgs);
person.call(this,name,age);
//派生类成员
this.work_no = work_no;
this.Desc = function()
{
return "Work No:" + this.work_no +"/n" + this.describe();
}
}
//--------------------------------------------------------------------
//-----------------测试区---------------------------------------------
var p1 = new person("陈小春",23);
alert(p1.describe());
var em = new employee("阿娇",22,"10001");
alert(em.Desc());
//--------------------------------------------------------------------
3. 实现命名空间。
例如:要实现 GrapeCity.LeySer.Payroll 的命名空间可以如下进行:
var GrapeCity= ( ( "undefined" == typeof( GrapeCity) ) ? {} : GrapeCity);
GrapeCity.LeySer= ( ( "undefined" == typeof( GrapeCity.LeySer) ) ? {} : GrapeCity.LeySer);
GrapeCity.LeySer.Payroll = ( ( "undefined" == typeof( GrapeCity.LeySer.Payroll ) ) ? {} : GrapeCity.LeySer.Payroll );
如果你感觉命名空间太长了,也可以用个短名代替(像C#的using spc=MySystem.Common;)
var Payroll = GrapeCity.LeySer.Payroll ;
Payroll.JinjiMasterItem = function( _name,_age)
{
this.Name = _name;
this.Age = _age;
}
同时这种用变量代替长命名空间的做法也可以实现类似VB.NET中的 with功能,用来实现简写。
4.深入理解arguments对象。
这里要清晰的概念是arguments是对象而不是数组。它下面几个重要属性:
length:说明函数实参的个数。
callee:是形参对象,arguments.callee.length是形参的个数。
caller:是函数的调用者。
它们的详细用法请看以下示例:
function testArguments()
{
//测试arguments是什么?(是对象,不是数组)
if(arguments instanceof Array )
{
alert("arguments是数组");
}
if(arguments instanceof Object )
{
alert("arguments是对象");
}
//打印arguments对象的每个成员的值
for( i = 0 ; i < arguments.length ;i++ )
{
alert("当前函数第"+(i+1).toString()+"个参值是:"+arguments[i]);
}
if (testArguments.caller)
{
alert("当前正在执行的函数是:/n" +arguments.callee.toString());
alert(testArguments.caller.length);
alert("调用testArguments的函数是:/n" +testArguments.caller.toString());
alert(testArguments.caller.length);
}
else
{
alert("这是个顶层调用");
}
}
function testCaller(a,b)
{
//arguments.callee 就是 testCaller函数自己
alert(arguments.callee.getName()+ "的形参个数:" + arguments.callee.length);
alert("testCaller的实参个数:" + arguments.length);
testArguments("你好,","这是函数参数测试。");
}
testCaller();
//arguments.callee 就是 testCaller函数自己 示例一个递归调用
function jc(n)
{
if ( n == 1 )
{
return 1;
}
else
{
return n*arguments.callee(n-1);
}
}
alert("5的阶乘是:" + jc(5));
注:在JS高级话题中我们要实现反射时可能会用 arguments 对象的某些特性,比如得到当前函数的名字,这时比较麻烦一点,我们需要给JS的Function对象通过Prototype注册一个方法来实现。
//给函数对象加getName方法来获取自己的名称
Function.prototype.getName = function() {
var s = Function.prototype.getName.caller.toString();
var m = s.match(/function/s+(/w+)/);
return m[1];
}
5.类的封装性,实现公有成员与私有成员。
GrapeCity.LeySer= ( ( "undefined" == typeof( GrapeCity.LeySer) ) ? {} : GrapeCity.LeySer);
GrapeCity.LeySer.Gakuhi = ( ( "undefined" == typeof( GrapeCity.LeySer.Gakuhi ) ) ? {} : GrapeCity.LeySer.Gakuhi );
GrapeCity.LeySer.Gakuhi.Student=function(menagementNo,name)
{
//私有变量
var mgNo=menagementNo;
var na=name;
//私有方法
var mycat = function()
{
return '学籍番号:'+mgNo+' 氏名:'+na;
};
//公共成员
return{
MenagementNo:mgNo,
Name:na,
FullInfo:function()
{
return mycat();
}
};
};
var s1= new GrapeCity.LeySer.Gakuhi.Student('H21001','相川 贞行');
undefined
s1.MenagementNo
"H21001"
s1.Name
"相川 贞行"
s1.FullInfo()
"学籍番号:H21001 氏名:相川 贞行"
s1.mgNo
undefined //因为mgNo是私有变量
s1.mycat(); //因为mycat是私有方法
TypeError: Object #<Object> has no method 'mycat'