征服Ajax-Web2.0开发技术详解试读版
一、JavaScript 中支持面向对象的基础
1.在JavaScript中,函数和类就是一个概念,当new一个函数时,就会返回一个对象。如果这个函数中没有初始化类成员,那就会返回一个空的对象。
2.在JavaScript中,每个对象可以看作是多个属性(方法)的集合,引用一个属性(方法)
很简单,即:
对象名.属性(方法)名
除此之外,还可以用方括号的形式来引用:
对象名[“属性(方法)名”]
3.在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译。JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为,可以动态添加、修改、删除属性和方法。
4.传统的面向对象语言中,每个对象都会对应到一个类。而上一节讲this 指针时提到,JavaScript 中的对象其实就是属性(方法)的一个集合,并没有严格意义的类的概念。所以它提供了另外一种简单的方式来创建对象,即大括号({})语法:
{
property1:statement,
property2:statement2,
…,
propertyN:statmentN
}
通过大括号括住多个属性或方法及其定义(这些属性或方法用逗号隔开),来实现对象的定义,这段代码就直接定义个了具有n个属性或方法的对象,其中属性名和其定义之间用冒号(:)隔开。
5.prototype 对象是实现面向对象的一个重要机制。每个函数(function)其实也是一个对象,它们对应的类是“Function”,但它们身份特殊,每个函数对象都具有一个子对象prototype。顾名思义,prototype 表示了该函数的原型,而函数也即是类,prototype 实际上就是表示了一个类的成员的集合。当通过new 来获取一个类的对象时,prototype 对象的成员都会成为实例化对象的成员。
二、深入认识JavaScript 中的函数
1.
function funcName(){
//函数体
}
//等价于
var funcName=function(){
//函数体
}
但前面一种方式创建的是有名函数,而后面是创建了一个无名函数,只是让一个变量指向了这个无名函数。在使用上仅有一点区别,就是:对于有名函数,它可以出现在调用之后再定义;而对于无名函数,它必须是在调用之前就已经定义。
2.Function是所有函数对象的基础,而Object则是所有对象(包括函数对象)的基础。在JavaScript中,任何一个对象都是Object的实例,因此,可以修改Object这个类型来让所有的对象具有一些通用的属性和方法,修改Object类型是通过prototype来完成的。
3.传递给函数的隐含参数:arguments
因此,在定义函数的时候,即使不指定参数列表,仍然可以通过arguments 引用到所获得的参数,这给编程带来了很大的灵活性。arguments对象的另一个属性是callee,它表示对函数对象本身的引用,这有利于实现无名函数的递归或者保证函数的封装性,例如使用递归来计算1 到n的自然数之和:
var sum=function(n){
if(1==n)return 1;
else return n+sum(n-1);
}
alert(sum(100));
其中函数内部包含了对sum自身的调用,然而对于JavaScript来说,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,所以使用arguments.callee属性会是一个较好的办法:
var sum=function(n){
if(1==n)return 1;
else return n+arguments.callee(n-1);
}
alert(sum(100));
4.JavaScript为函数对象定义了两个方法:apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
与 arguments 的length属性不同,函数对象的还有一个参数相关的属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
function sum(a,b){
return a+b;
}
alert(sum.length);
5.JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合,而是可以动态的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。
三、类的实现
1.尽管前面介绍了如何定义一个类,如何初始化一个类的实例,但既可以在function定义的函数体中添加成员,又可以用prototype 定义类的成员,代码显的很混乱,和面向对象语言类的实现之间有着很大的区别。那么,如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式,并将它们对应到面向对象语言类的实现上。
类的构造函数用来初始化一个实例,是每个类必不可少的一部分。在传统意义的面向对象中,类的构造函数的名称和类的名称一致,同时它们的定义方式和类成员的定义是类似而又相互独立的。而在JavaScript中,由于对象的灵活的性质,在构造函数中也可以为类添加成员,在增加灵活性的同时,也增加了代码的复杂度。为了提高代码的可读性和开发效率,完全可以抛弃这种定义成员的方式,而使用prototype 对象来替代,这样function 的定义就是类的构造函数,符合传统意义类的实现:类名和构造函数名是相同的。
四、公有成员、私有成员和静态成员
1.私有成员即在类的内部实现中可以共享的成员,但是并不对外公开。JavaScript 中并没有特殊的机制来定义私有成员,但可以用一些技巧来实现这个功能。
2.这个技巧主要是通过变量的作用域性质来实现的,在JavaScript中,一个函数内部定义的变量称为局部变量,该变量不能够被函数外的程序所访问,却可以被函数内部定义的嵌套函数所访问。在实现私有成员的过程中,正是利用了这一性质。
五、使用for(…in…)实现反射机制
1.反射机制指的是程序在运行时能够获取自身的信息。例如一个对象能够在运行时知道自己有哪些方法和属性,这属于高级的面向对象程序设计的功能。在C#中,利用程序集中的元数据来实现反射,能够在运行时动态判断和调用自己的属性或方法。
六、类的继承
1.在JavaScript 中,除了基本的数据类型(数字、字符串、布尔等),所有的赋值以及函数参数都是引用传递,而不是值传递。
2.前面一节介绍的共享prototype 来实现类的继承,并不是一种很好的方法,毕竟两个类是共享的一个prototype,任何对成员的重定义都会互相影响,不是严格意义的继承。但在这个思想的基础上,可以利用反射机制来实现类的继承,思路如下:利用for(…in…)语句枚举出所有基类prototype的成员,并将其赋值给子类的prototype对象。
七、实现抽象类
1.虚函数是类成员中的概念,即只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现。抽象类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不能被调用。所以抽象类一般只作为基类被派生以后再使用。
和类的继承一样,JavaScript 并没有任何机制用于支持抽象类,其实继承都没有,更何况抽象类了。但利用JavaScript语言本身的性质,可以实现自己的抽象类。
2.解释型语言执行的特点,它们只有在运行到某一个方法调用时,才会检查该方法是否存在,而不会向编译型语言一样在编译阶段就检查方法存在与否。JavaScript 中则避免了这个问题。当然,如果希望在基类中添加虚方法的一个定义,也是可以的,只要在派生类中覆盖此方法即可。
八、事件设计模式
1.事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有onchange事件,通过这些事件可以方便编程。那么对于自己定义的类,是否也实现事件机制呢?答案是肯定的,通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率。
九、实例:使用面向对象思想处理cookie
1.对于cookie 的处理,事实上只是封装一些方法,每个对象不会有状态,所以不需要创建一个cookie 处理类,而只用一个全局对象来联系这些cookie 操作。对象名可以理解为命名空间。
JavaScript 高级技术
一、框架间的互相引用
1.一个页面中的所有框架以集合的形式作为window 对象的属性提供,例如:
window.frames 就表示该页面内所有框架的集合,这和表单对象、链接对象、图片对象等是类似的,不同的是,这些集合是document 的属性。因此,要引用一个子框架,可以使用如下语法:
window.frames[“frameName”];
window.frames.frameName
window.frames[index]
其中,window字样也可以用self代替或省略,假设frameName 为页面中第一个框架,则以下的写法是等价的:
self.frames[“frameName”]
self.frames[0]
frames[0]
frameName
二、改变框架的载入页面
1.前面已经讲到,对框架的引用就是对window对象的引用,利用window对象的location属性,可以改变框架的导航,例如:
window.frames[0].location=”1.html”;
三、引用其他框架内的JavaScript变量和函数
1.框架可以使一个页面划分为功能独立的多个模块,每个模块之间彼此独立,但又可以通过window 对象的引用来建立联系,是web 开发中的一个重要机制。在Ajax 开发中,还可以利用隐藏框架实现各种技巧,在后面介绍Ajax 实例编程时可以发现,无刷新上传文件以及解决Ajax的前进后退问题都会用到这种技术。
使用cookie
一、cookie概述
准确的说,cookie是浏览器提供的一种机制,它将document对象的cookie属性提供给JavaScript。可以由JavaScript对其进行控制,而并不是JavaScript本身的性质。简单的来讲,cookie是存于用户硬盘的一个文件,这个文件通常对应于一个域名,当浏览器再次访问这个域名时,便使这个cookie 可用。因此,cookie 可以跨越一个域名下的多个网页,但不能跨越多个域名使用。
cookie机制将信息存储于用户硬盘,因此可以作为全局变量,这是它最大的一个优点。
一般来讲,它可以用于以下几种场合:
a.保存用户登录状态。例如将用户id 存储于一个cookie 内,这样当用户下次访问该页面时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。cookie还可以设置过期时间,当超过时间期限后,cookie就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个月、一年等。
b.跟踪用户行为。例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况。如果每次都需要选择所在地是烦琐的,当利用了cookie 后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区的天气情况。因为一切都是在后台完成,所以这样的页面就像为某个用户所定制的一样,使用起来非常方便。
c.定制页面。如果网站提供了换肤或更换布局的功能,那么可以使用cookie 来记录用户的选项,例如:背景色、分辨率等。当用户下次访问时,仍然可以保存上一次访问的界面风格。
d.创建购物车。正如在前面的例子中使用cookie 来记录用户需要购买的商品,在结帐的时候可以统一提交。例如淘宝网就使用cookie记录了用户曾经浏览过的商品,方便随时进行比较。
当然,上述应用仅仅是cookie 能完成的部分应用,还有更多的功能需要全局变量。任何事情都有正反两面,cookie也不例外,它的缺点主要集中于安全性和隐私保护。主要包括以下几种:
a.cookie 可能被禁用。当用户非常注重个人隐私保护时,他很可能禁用浏览器的cookie功能。
b.cookie是浏览器相关的。这意味着即使访问的是同一个页面,不同浏览器之间所保存的cookie也是不能互相访问的。
c.cookie 可能被删除。因为每个cookie 都是硬盘上的一个文件,因此很有可能被用户删除。
d.cookie 安全性不够高。所有的cookie 都是以纯文本的形式记录于文件中,因此如果要保存用户名密码等信息时,最好事先经过加密处理。
二、综合示例:构造通用的cookie处理函数
cookie 的处理过程比较复杂,但都具有一定的相似性。因此可以定义几个函数来完成cookie的通用操作,从而实现代码的复用。下面列出了常用的cookie操作及其函数实现。
1.添加一个cookie:addCookie(name,value,expireHours)
该函数接收3 个参数:cookie 名称,cookie 值,以及在多少小时后过期。这里约定 expireHours为0 时不设定过期时间,即当浏览器关闭时cookie自动消失。该函数实现如下:
<script language="JavaScript" type="text/javascript">
<!--
function addCookie(name,value,expireHours){
var cookieString=name+"="+escape(value);
//判断是否设置过期时间
if(expireHours>0){
var date=new Date();
date.setTime(date.getTime+expireHours*3600*1000);
cookieString=cookieString+"; expire="+date.toGMTString();
}
document.cookie=cookieString;
}
//-->
</script>
2.获取指定名称的cookie值:getCookie(name)
该函数返回名称为name的cookie值,如果不存在则返回空,其实现如下:
<script language="JavaScript" type="text/javascript">
<!--
function getCookie(name){
var strCookie=document.cookie;
var arrCookie=strCookie.split("; ");
for(var i=0;i<arrCookie.length;i++){
var arr=arrCookie[i].split("=");
if(arr[0]==name)return arr[1];
}
return "";
}
//-->
</script>
3.删除指定名称的cookie:deleteCookie(name)
该函数可以删除指定名称的cookie,其实现如下:
<script language="JavaScript" type="text/javascript">
<!--
function deleteCookie(name){
var date=new Date();
date.setTime(date.getTime()-10000);
document.cookie=name+"=v; expire="+date.toGMTString();
}
//-->
</script>
三、使用正则表达式
javaScript search和indexOf方法不同,该方法接收的是一个正则表达式,而indexOf只能接收一个字符串。但两者的行为是类似的。
四、使用window对象
1.使用定时器实现JavaScript的延期执行或重复执行
window 对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和window.setInterval。其中前者可以使一段代码在指定时间后运行;而后者则可以使一段代码每过指定时间就运行一次。它们的原型如下:
window.setTimeout(expression,milliseconds);
window.setInterval(expression,milliseconds);
其中,expression可以是用引号括起来的一段代码,也可以是一个函数名,到了指定的时间,系统便会自动调用该函数,当使用函数名作为调用句柄时,不能带有任何参数;而使用字符串时,则可以在其中写入要传递的参数。两个方法的第二个参数是milliseconds,表示延时或者重复执行的毫秒数
如果在延时期限到达之前取消延时执行,可以使用window.clearTimeout(timeoutId)方法,该方法接收一个id,表示一个定时器。这个id是由setTimeout方法返回。
如果想要取消定时执行,和clearTimeout 方法类似,可以调用window.clearInterval 方法。clearInterval 方法同样接收一个setInterval方法返回的值作为参数。
五、使用alert、prompt和confirm语句与用户进行交互
异常处理
一、使用try-catch-finally处理异常
用户可以使用该结构处理可能发生异常的代码,如果发生异常,则由catch捕获并进行处理,其语法如下:
try{
//要执行的代码
}
catch(e){
//处理异常的代码
}
finally{
//无论异常发生与否,都会执行的代码
}
参考文档:
http://www.w3school.com.cn/jsref/jsref_obj_global.asp
http://larrycaiyu.com
http://www.blogjava.net/eamoi
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。