您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > JavaScript的高级话题
-1-第1页共45页JavaScript面向对象的支持很少有人对JavaScript的面向对象特性进行系统的分析。我希望接下来的文字让你了解到这个语言最少为人知的一面。一、JavaScript中的类型虽然JavaScript是一个基于对象的语言,但对象(Object)在JavaScript中不是第一型的。JS是以函数(Function)为第一型的语言。这样说,不但是因为JS中的函数具有高级语言中的函数的各种特性,而且也因为在JS中,Object也是由函数来实现的。——关于这一点,可以在后文中‚构造与析构‛部分看到更进一步的说明。JS中是弱类型的,他的内置类型简单而且清晰:undefined:未定义number:数字boolean:布尔值string:字符串function:函数object:对象1).undefined类型:在IE5及以下版本中,除了直接赋值和typeof()之外,其它任何对undefined的操作都将导致异常。如果需要知道一个变量是否是undefined,只能采用typeof()的方法:1.script2.varv;3.if(typeof(v)=='undefined'){//...}4./script但是在IE5.5及以上版本中,undefined是一个已实现的系统保留字。因此可以用undefined来比较和运算。检测一个值是否是undefined的更简单方法可以是:1.script2.varv;3.if(v===undefined){//...}4./script因此为了使得核心代码能(部分地)兼容IE5及早期版本,Romo核心单元中有一行代码用来‚声明‛一个undefined值:1.//codefromQomolangma,inJSEnhance.js2.varundefined=voidnull;这一行代码还有一点是需要说明的,就是void语句的应用。void表明‚执行其后的语句,且忽略返回值‛。因此在void之后可以出现能被执行的任何‚单个‛语句。而执行的结果就是undefined。当然,如果你愿意,你也可以用下面的代码之一‚定义undefined‛。-2-第2页共45页1.//1.较复杂的方法,利用一个匿名的空函数执行的返回2.varundefined=function(){}();3.//2.代码更简洁,但不易懂的方法4.varundefined=void0;void也能像函数一样使用,因此void(0)也是合法的。有些时候,一些复杂的语句可能不能使用void的关键字形式,而必须要使用void的函数形式。例如:1.//必须使用void()形式的复杂表达式2.void(i=1);//或如下语句:3.void(i=1,i++);2).number类型:JavaScript中总是处理浮点数,因此它没有象Delphi中的MaxInt这样的常量,反而是有这样两个常值定义:Number.MAX_VALUE:返回JScript能表达的最大的数。约等于1.79E+308。Number.MIN_VALUE:返回JScript最接近0的数。约等于2.22E-308。因为没有整型的缘故,因此在一些关于CSS和DOM属性的运算中,如果你期望取值为整数2,你可能会得到字符串‚2.0‛——或者类似于此的一些情况。这种情况下,你可能需要用到全局对象(Gobal)的parseInt()方法。全局对象(Gobal)中还有两个属性与number类型的运算有关:NaN:算术表达式的运算结果不是数字,则返回NaN值。Infinity:比MAX_VALUE更大的数。如果一个值是NaN,那么他可以通过全局对象(Gobal)的isNaN()方法来检测。然而两个NaN值之间不是互等的。如下例:1.//NaN的运算与检测2.varv1=10*'a';3.varv2=10*'a';4.document.writeln(isNaN(v1));5.document.writeln(isNaN(v2));6.document.writeln(v1==v2);全局对象(Gobal)的Infinity表示比最大的数(Number.MAX_VALUE)更大的值。在JS中,它在数学运算时的价值与正无穷是一样的。——在一些实用技巧中,它也可以用来做一个数组序列的边界检测。Infinity在Number对象中被定义为POSITIVE_INFINITY。此外,负无穷也在Number中被定义:Number.POSITIVE_INFINITY:比最大正数(Number.MAX_VALUE)更大的值。正无穷。Number.NEGATIVE_INFINITY:比最小负数(-Number.MAX_VALUE)更小的值。负无穷。与NaN不同的是,两个Infinity(或-Infinity)之间是互等的。如下例:1.//Infinity的运算与检测2.varv1=Number.MAX_VALUE*2;3.varv2=Number.MAX_VALUE*3;4.document.writeln(v1);5.document.writeln(v2);6.document.writeln(v1==v2);-3-第3页共45页在Global中其它与number类型相关的方法有:isFinite():如果值是NaN/正无穷/负无穷,返回false,否则返回true。parseFloat():从字符串(的前缀部分)取一个浮点数。不成功则返回NaN。3).boolean类型:(略)……4).string类型:JavaScript中的String类型原本没有什么特殊的,但是JavaScript为了适应‚浏览器实现的超文本环境‛,因此它具有一些奇怪的方法。例如:link():把一个有HREF属性的超链接标签A放在String对象中的文本两端。big():把一对big标签放在String对象中的文本两端。以下方法与此类同:anchor()blink()bold()fixed()fontcolor()fontsize()italics()small()strike()sub()sup()除此之外,string的主要复杂性来自于在JavaScript中无所不在的toString()方法。这也是JavaScript为浏览器环境而提供的一个很重要的方法。例如我们声明一个对象,但是要用document.writeln()来输出它,在IE中会显示什么呢?下例说明这个问题:1.//toString()的应用2.vars=newObject();3.s.v1='hi,';4.s.v2='test!';5.document.writeln(s);6.document.writeln(s.toString());7.s.toString=function(){returns.v1+s.v2;}8.document.writeln(s);在这个例子中,我们看到,当一个对象没有重新声明(覆盖)自己toString()方法的时候,那么它作为字符串型态使用时(例如被writeln),就会调用JavaScript环境缺省的toString()。反过来,你也可以重新定义JavaScript理解这个对象的方法。很多JavaScript框架,在实现‚模板‛机制的时候,就利用了这个特性。例如他们用这样定义一个FontElement对象:1.//利用toString()实现模板机制的简单原理2.functionFontElement(innerHTML){3.this.face='宋体';4.this.color='red';5.//more...6.varctx=innerHTML;7.this.toString=function(){8.return'FontFACE='+this.face+'COLOR='+this.color+''+ctx+'/FONT';9.}10.}-4-第4页共45页11.varobj=newFontElement('这是一个测试。');12.//留意下面这行代码的写法13.document.writeln(obj);5).function类型:javascript函数具有很多特性,除了面向对象的部分之外(这在后面讲述),它自已的一些独特特性应用也很广泛。首先javascript中的每个函数,在调用过程中可以执有一个arguments对象。这个对象是由脚本解释环境创建的,你没有别的方法来自己创建一个arguments对象。arguments可以看成一个数组:它有length属性,并可以通过arguments[n]的方式来访问每一个参数。然而它最重要的,却是可以通过callee属性来得到正在执行的函数对象的引用。接下的问题变得很有趣:Function对象有一个caller属性,指向正在调用当前函数的父函数对象的引用——我们已经看到,我们可以在JavaScript里面,通过callee/caller来遍历执行期的调用栈。由于arguments事实上也是Function的一个属性,因此我们事实上也能遍历执行期调用栈上的每一个函数的参数。下面的代码是一个简单的示例:1.//调用栈的遍历2.functionfoo1(v1,v2){3.foo2(v1*100);4.}5.functionfoo2(v1){6.foo3(v1*200);7.}8.functionfoo3(v1){9.varfoo=arguments.callee;10.while(foo&&(foo!=window)){11.document.writeln('调用参数:br','---------------br');12.varargs=foo.arguments,argn=args.length;13.for(vari=0;iargn;i++){14.document.writeln('args[',i,']:',args[i],'br');15.}16.document.writeln('br');17.//上一级18.foo=foo.caller;19.}20.}21.//运行测试22.foo1(1,2);二、JavaScript面向对象的支持在前面的例子中其实已经讲到了object类型的‚类型声明‛与‚实例创建‛。在JavaScript中,我们需要通过一个函数来声明自己的object类型:1.//JavaScript中对象的类型声明的形式代码(以后的文档中,“对象名”通常用MyObject来替代)2.function对象名(参数表){3.this.属性=初始值;4.this.方法=function(方法参数表){//方法实现代码……}-5-第5页共45页5.}然后,我们可以通过这样的代码来创建这个对象类型的一个实例:1.//创建实例的形式代码(以后的文档中,“实例变量名”通常用obj来替代)2.var实例变量名=new对象名(参数表);接下来我们来看‚对象‛在JavaScript中的一些具体实现和奇怪特性。1).函数在JavaScript的面向对象机制中的五重身份‚对象名‛——如MyObject()——这个函数充当了以下语言角色:普通函数类型声明类型的实现类引用对象的构造函数一些程序员(例如Delphi程序员)习惯于类型声明与实现分开。例如在delphi中,Interface节用于声明类型或者变量,而implementation节用于书写类型的实现代码,或者一些用于执行的函数、代码流程。但在JavaScript中,类型的声明与实现是混在一起的。一个对象的类型(类)通过函数来声明,this.xxxx表明了该对象可具有的属性或者方法。这个函数的同时也是‚类引用‛。在JavaScript,如果你需要识别一个对象的具体型别,你需要执有一个‚类引用‛。——当然,也就是这个函数的名字。instanceof运算符就用于识别实例的类型,我们来看一下它的应用:1.//JavaScrip
本文标题:JavaScript的高级话题
链接地址:https://www.777doc.com/doc-6332721 .html