javascript的高级特性
javaScript OOP
JavaScript的对象总有4类:
脚本对象:如Object,Math,Date 等。
浏览器对象:window,document,location等。
Dom对象:对dom操作的对象,document,Node等
自定义对象:程序员自身定义的对象。
本次介绍程序员如何定义对象,对象是由类创建出来的,在Java中,我们可以通过语法:
类 obj=new 类();
来定义对象,那么在JavaScript中如何定义对象呢?
在JavaScript中,我们首先讨论一下JavaScript的一个重要特性:动态性。
JavaScript是一门动态语言,什么意思呢?我认为包含两个含义:
一是任何变量都可以不用考虑数据类型,在运行时才能区分当前变量的数据类型,也就是说JavaScript是弱类型的,在声明变量时,变量类型都是var ,不能是Object ,String,Date等。比如:
var a=1; //此时变量a是数字类型
a="hello"; //此时变量a是字符串类型
a=new Object(); 此时变量a是对象
上面程序运行没有问题。
动态性的第二个含义是对象属性可以在运行时,动态添加属性和方法,我们知道,在JavaScript中,任何对象都是Object的子类。有如下示例:
var obj=new Object();
obj.name="Jerry";
obj.sayHello=function ()
{
alert("Hello,world!");
}
alert(obj.name);
obj.sayHello();
我们在上面的代码里,动态的为一个对象obj添加一个属性name 和一个方法sayHello.
在JavaScript中任何函数都可以new,例如:
function Hello()
{
alert("Hello");
}
var h=new Hello();
上面代码的解释是:创建一个对象h,对象没有任何属性和方法。在new一个函数时,函数的函数体自动执行,此时,函数体就犹如对象的构造方法。
继续观察如下代码:
function Hello()
{
var obj=new Object();
obj.name="Jerry";
return obj;
}
var h=new Hello();
alert(h.name);
输出Jerry;
这时,对象h就是函数返回的Object对象,因此可以说,JavaScript通过 new 函数() 这样的语法来获取对象时,如果函数有return ,那么return 的结果就是实例化后的对象。
另一方面,在JavaScript中,与java一样,任何对象都有内部关键字this ,表示当前对象,那么一个函数既然是对象的构造方法,能否这样使用呢?
function Hello()
{
this.name="Jerry";
}
var h=new Hello();
alert(h.name);
运行结果与前面的一样,此时,该函数就与java中的类有点相似了,那么如何添加方法呢?可以这样:
function Hello()
{
this.name="Jerry";
this.sayHello=function()
{
alert("Hello,world");
}
}
var h=new Hello();
//alert(h.name);
h.sayHello();
OK,到此为止,类就定义出来了,接下来我们看看讨论一下JavaScript的封装,继承,多态。
封装,不用说了,既然是类,那么天生就具备封装功能,只不过这里类的所有属性和方法都是public 的,这一点与java不一样。
继承,就是扩展,在JavaScript中,任何时候都可以动态的给对象添加属性和方法,那么是不是就是继承呢?也可以这么理解:
function SubHello()
{
var h=new Hello();
h.age=20;
return h;
}
var sub=new SubHello();
sub.sayHello();
alert(sub.age);
我们可以看出,调用结果正常运行,但是这种继承方式感觉别扭,JavaScript给我们提供了一个关键字,prototype,就是原型的意思。先测试一下使用方法
Hello.prototype.age=20;
var h=new Hello();
alert(h.age);
运行结果正常20。
封装为函数实现继承
function SubHello()
{
Hello.prototype.age=20;
return new Hello();
}
这就是说SubHello是从Hello继承过来,并且发生的扩展。
接下来看看多态,多态形式是把子类对象赋值给父类的引用,但是在JavaScript中所有的对象都是var类型的,因此,JavaScript天生就是多态的,其实任何动态语言天生就是多态的,如Ruby.
当然,JavaScript不支持方法重载,这一点非常重要。
我们看看对象调用。
调用属性:
var h=new Hello();
alert(h.name);
着非常简单。其实JavaScirpt对象就是属性和方法的集合,因此我们调用属性时可以这样调用:
var h=new Hello();
alert(h["name"]);
并且对象动态添加属性时也可以这样:
var h=new Hello();
h["test"]=1234;
alert(h.test);
结果正常。
调用方法:
方法定义的时候可以是这样的
var h=new Hello();
h.testMethod=function()
{
alert("test");
}
可以看出,这个地方就是c语言中的函数指针,可以把方法进行赋值,方法名称就是方法的地址,因此还可以这样:
function test(){
alert("test");
}
h.testMethod=test;
既然函数的名称就是函数的指针,当然和c语言一样不能对方法进行重载。那么如何传递参数呢?
function test(a,b,c)
{
alert(a+b+c);
}
test(1,2,3);
上面函数调用是正常的方法,那么这样调用呢:
test(1,2,3,4,5);
当然也能正常运行,因为函数名是函数的唯一地址,那么参数4,5呢?丢失了吗?
当函数传递参数时,所有的参数保存在JavaScirpt的内置对象arguments中,可以这样得到结果。
function test()
{
if(arguments.length>=3)
{
return arguments[0]+arguments[1]+arguments[2];
}
}
alert(test(1,2,3));
这就是方法调用时要注意的地方arguments。