JavaScript高级编程.ppt
第5章 JavaScript高级编程,课程回顾,Web Service具有以下优势:平台无关性编程语言无关性部署、升级和维护Web服务简单对于Web服务使用者来说,可以轻易实现多种数据、服务的聚合成本低数据不受防火墙阻挡.NET中创建的Web Service都派生自System.Web.Services.WebService类Web服务方法都必须满足两个条件:由WebMethod特性标识、public访问修饰符简单对象访问协议(SOAP)是基于XML的轻量级协议,可以实现在Internet上任意位置调用已发布的Web ServiceWSDL与SOAP和UDDI(统一描述、发现和集成机制)一起工作,支持Web服务与Internet上的其他服务、应用程序和设备交互作用。UDDI提供了发布和定位Web服务的功能,WSDL描述了Web服务,SOAP为Web服务提供了传输消息在.NET各种类型的应用程序中,都可以通过“添加Web引用”的方式创建客户端代理类来调用Web Service,也可以通过动态生成客户端代理类来调用,本章内容,JavaScript变量作用域JavaScript函数JavaScript面向对象编程JavaScript闭包JavaScript处理JSON数据,本章目标,深入了解JavaScript的变量作用域能够使用JavaScript进行面向对象编程理解JavaScript中闭包的概念和作用理解JSON数据的格式及使用JavaScript处理JSON数据,1.JavaScript重点回顾,1.1 数组,一个JavaScript数组的元素可以具有任意的数据类型,同一个数组的不同元素可以具有不同的类型,数组的元素设置可以包含其他数组,var a=北京,上海,true,1,20,深圳;with(document)writeln(遍历数组a的值是:);for(var i=0;ia.length;i+)writeln(a+i+=+ai);,使用 创建数组,var a=new Array(北京,上海,true,1,20,深圳);with(document)writeln(遍历数组a的值是:);for(var i=0;ia.length;i+)writeln(a+i+=+ai);,使用new关键字创建数组对象Array(),数组,数组元素,数组的长度可以通过length属性获得,并且数组的长度是可变化的,var a=new Array();/起始长度为0 var b=new Array(5,4,3,false,Tom,3.14);/长度为6 var c=new Array(20);/长度为20/错误的数组定义,定义长度必须是整数;否则,至少要2个元素 var d=new Array(3.14);var d=new Array(tom,3.14);/合法,长度为2a3=Test;/a的长度自动变为4,数组的元素可以是任何类型数据,数组的长度可以变化,数组,访问数组元素,访问数组的元素使用运算符,可以通过下标访问,也可以通过关键字访问,var a=new Array(jack,true,one:one,two:two,three:three);var b=new Array(5,4,3,false,Tom,3.14);a1.23=test;with(document)writeln(a1.23=+a1.23);writeln(a.length=+a.length);writeln(a2.one=+a2.one);writeln(a2two=+a2two);btrue=true;with(document)writeln(b.length=+b.length);writeln(btrue=+btrue);writeln(b6=+b6);/索引溢出,但不会出错,值是undefined for(i in b)document.writeln(b+i+=+bi);,为数组a添加了一个元素,访问第3个元素(对象)的属性,for in 遍历数组元素,1.1 数组,多维数组,数组元素可以是任何类型的数据(包括另一个数组),可以非常方便地模拟多维数组,var one=new Array(3);for(var i=0;ione.length;i+)onei=new Array(4);for(var j=0;j onei.length;j+)oneij=(i+1)*(j+1);,arrayA=21,22,23,31,32,33,34;for(var i=0;i arrayA+i+j+=+arrayAij);,使用new Array()创建多维数组,使用 创建多维数组,1.1 数组,数组排序,使用Array对象的sort()方法,该方法允许传递一个排序函数作为参数。如果不传递参数,则按照ASCII字符顺序升序排列,var a=new Array(10,215,324,3,1254,300);function sortFunction(one,two)return one-two;a.sort();for(i in a)document.writeln(ai);document.writeln();a.sort(sortFunction);for(i in a)document.writeln(ai);,作为sort()方法的参数传递的函数,无参数,按ASCII字符顺序升序排列,传递参数,按参数指定的排序规则排序,function 函数名(形参列表)执行语句return 返回值;/可选的语句,1.2 函数,命名函数的创建和调用,函数也是一种数据类型,是function类型。所以只要使用function关键字标识一个函数名,就可以在大括号内编写代码,并且可以被调用、作为其他函数的参数或者作为对象的属性值,var n0=factorial$(0);var n10=factorial$(10);var n20=factorial$(20);alert(0的阶乘为:+n0+n10的阶乘为:+n10+n20的阶乘为:+n20);,调用函数,function factorial$(n)var out=1;if(n=0)return out;for(var i=1;i=n;i+)out*=i;return out;,创建计算阶乘的函数,函数,函数的参数和返回值参数名可以重复,但通过此参数名获取的值为实际传递参数的最后一个,如果实际传递参数值的个数小于重名参数的个数,那么通过此参数名获取的值为undefined即使声明了形参,调用时也可以不传递参数不管形参有几个,传递实参可以和形参个数不同在函数被调用时,会创建一个arguments对象,负责管理参数参数和返回值都可以是任何类型,包括function类型函数可以不需要return语句来返回值,即使没有return语句,函数也会返回值,这种情况下返回值是undefined,function fnArgs()var result=;for(var i=0;i arguments.length;i+)result+=argumentsi+,;result=result.substring(0,result.length-1);return result;function fnReturn()function fnArgsIterate()return a+b;var a=5,a=6,b=7;alert(为fnArgs()传递的实参是:+fnArgs(3,shanghai,3.14)+n函数fnReturn()返回值是:+fnReturn()+n为fnArgsInterate()传递了重复参数,结果是:+fnArgsIterate(a,a,b);,函数,内部函数和匿名函数,在一个函数内部,可以把另一个函数作为数据使用,这就形成了内部函数,var fn=function()return a+b;var a=10,b=20;document.writeln(fn(a,b)+);,创建匿名函数,var func=function()return function()document.writeln(函数返回值是一个内部函数);func()();(function()document.writeln(创建即运行);)();,创建内部函数,调用内部函数,小结1,创建数组的方式有哪几种?如何创建多维数组?如何访问数组元素?如何对数组排序,2.JavaScript面向对象编程,2.1 对象,对象是无序属性的集合,属性可以是任何类型的值,包括其他的对象或函数,当函数作为属性值时称作“方法”,即对象的行为,常用对象的内部属性,对象,对象的创建、访问和释放,创建对象,var 对象名=new 构造函数(),对象,常用内置对象,Global对象Global对象没有construct属性,所以无法使用new操作符构造没有call属性,所以无法像函数一样调用Global对象只是一个概念,表示全局对象,依据宿主不同而不同。例如在浏览器中,window就是Global对象,var lan=zh;var money=3000;function getLan()var money=5000;var g=this=window;/this指向window/lan是window的属性,money是window的money属性,值为3000 document.writeln(g+n+this.lan+n+this.parseFloat(this.money);/getLan()是window的属性 window.getLan();,所有的变量和函数都是Global对象的属性,如果有同名,则后定义的覆盖先定义,想想看:this.money的值是3000还是5000?,对象,常用内置对象,Object对象:Object对象是所有对象的基础,任何其他对象都是从Object对象原型扩展而来 如果为Object对象使用原型扩展了属性,则所有对象都具有此属性,Object.prototype.money=3000;document.writeln(添加了原型属性money,值为:+Object.money);Object.money=5000;document.writeln(生成了对象属性money,值为:+Object.money);var s=new String();/String也因为Object原型扩展而拥有了money属性document.writeln(String对象继承了money属性,值为:+s.money);,想想看:s.money的值是3000还是5000?,对象,常用内置对象,Function对象:当使用function关键字定义了一个函数时,在系统内部实际上时创建了一个Function对象,因为函数也是对象,函数的调用,函数名();apply(this,函数参数数组);call(this,函数参数列表);,var s=new String();s.money=1000;/money是String对象的属性 var money=2000;/money是window对象的属性 var func1=new Function(a,b,document.writeln(a+b);document.writeln(this.money+););var func2=function(a,b)document.writeln(a+b);document.writeln(this.money+);/因为没有传递对象引用,所以func1()函数中的this指向window func1(10,20);/传递了对象s,所以func1中的this指向s func1.apply(s,10,20);/传递的空引用,所以func2中的this指向了window func2.call(null,10,20);,使用new关键字调用构造函数创建函数对象,this指向因调用方式不同而不同,对象,常用内置对象,Error对象:可以在发生错误时作为参数传递给catch子句,也可以使用new关键字构造自定义的Error对象,tryvar myerr=new Error(“自定义错误”);/自定义错误对象throw myerr;/抛出自定义的错误对象catch(e)alert(e.message);/message属性是Error对象最主要的属性,2.2 类的模拟,实体类,实体类是自定义类型,需要定义后才可以使用它创建对象。在JavaScript中没有class,但可以通过用function关键字和this关键字类定义类模板,function 类名(参数1,参数2参数n)this.属性名=参数1;this.属性名=参数2;this.属性名=参数n;,function Teacher(n,s,a)/绑定属性 this.name=n;this.sex=s;this.age=a;/绑定行为Teacher.prototype.getDetails=function()document.writeln(教员的姓名:+this.name+教员的性别:+this.sex+教员的年龄:+this.age);/创建对象var tea=new Teacher(Mary,女,25);/调用方法tea.getDetails();,function Teacher(n,s,a)/绑定属性 this.name=n;this.sex=s;this.age=a;/判断行为是否已经定义过 if(Teacher.prototype.getDetails=undefined)/绑定行为 Teacher.prototype.getDetails=function()document.writeln(教员的姓名:+this.name+教员的性别:+this.sex+教员的年龄:+this.age);,直接将行为的绑定放在类定义的括号内,类的模拟,类的继承,通过原型扩展的方式实现继承,function Person()this.name=Jack;Person.prototype.speak=function()document.writeln(Person类的原型扩展的方法speak被继承);Person.prototype.eat=function()document.writeln(Person类的原型扩展的方法eat被继承);function Student()Student.prototype.study=function()document.writeln(Student类自己的方法);/实现继承Student.prototype=new Person();/测试继承 var stu=new Student();/继承的方法stu.speak();stu.eat();/自己的方法stu.study();,小结2,Global对象与浏览器的window对象由什么关系?apply()与call()方法有什么区别?如何实现类的继承?,3.JavaScript闭包,3.1 什么是JavaScript闭包,“闭包”是指一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分,在函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量(闭包是一种间接保持变量值的机制)。当一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包,function funcTest()var tmpNum=100;/私有变量/在函数funcTest内定义另外的函数作为funcTest的方法函数 function innerFuncTest()alert(tmpNum);/引用外层函数funcTest的临时变量tmpNum return innerFuncTest;/返回内部函数/调用函数var myFuncTest=funcTest();myFuncTest();/弹出100/下面的调用将失败innerFuncTest();,什么是JavaScript闭包,变量作用域,内部函数也可以有自己的变量和函数,但其作用域只能是内部函数体内,function funcTest()var tmpNum=100;/私有变量/在函数funcTest内定义另外的函数作为funcTest的方法函数 function innerFuncTest()var innerVar=0;alert(innerVar+);alert(tmpNum+);/引用外层函数funcTest的临时变量tmpNum return innerFuncTest;/返回内部函数 var myFuncTest=funcTest();myFuncTest();/弹出0后再弹出100,innerVar的作用域仅限于函数innerFuncTest()内,什么是JavaScript闭包,变量作用域,内部函数可以引用全局变量或函数以及外部函数定义的变量或函数,var globalVar=0;function funcTest()var tmpNum=100;/私有变量 function innerFuncTest()var innerVar=0;alert(innerVar+);/引用内部函数变量 alert(tmpNum+);/引用外层函数funcTest的临时变量tmpNum alert(+globalVar);/引用全局变量 return innerFuncTest;/返回内部函数var myFuncTest=funcTest();myFuncTest();/弹出0、100和1,什么是JavaScript闭包,变量作用域,如果内部函数引用了位于外部函数中的变量,相当于授权该变量能够被延迟使用。因此,当外部函数调用完成后,这些变量的内存不会释放,因为闭包还引用这它们,在JavaScript中,如果一个对象不再被引用,该对象将被GC回收。如果两个对象互相引用,而不再被第三者所引用,那么这两个互相引用的对象也会被回收,什么是JavaScript闭包,变量作用域,每次通过引用调用内部函数,内部函数内部的局部变量都会被重新创建,var globalVar=0;function funcTest()var tmpNum=100;/私有变量/在函数funcTest内定义另外的函数作为funcTest的方法函数 function innerFuncTest()var innerVar=0;document.writeln(innerVar+,+tmpNum+,+globalVar+);return innerFuncTest;/返回内部函数var first=funcTest();first();/显示0、100和1first();/显示0、101和2,注意:函数的局部变量tmpNum被保存下来,没有销毁var second=funcTest();second();/显示0、100和3second();/显示0、101和4,什么是JavaScript闭包,闭包的使用,利用闭包绑定参数为函数引用设置延时,function closureExample(msg)return function()alert(msg);/使用闭包解决window.onload=function()var element=document.getElementById(closuretest);if(element)var good=closureExample(这个参数是由闭包绑定的);element.onclick=function()setTimeout(good,3000);/延迟3秒弹出提示,通过闭包为setTimeout传入参数,什么是JavaScript闭包,闭包的使用,通过对象实例方法关联函数,function associateObjWithEvent(obj,methodName)return(function()return objmethodName(this););function HtmlEle(elementId)var el=document.getElementById(elementId);if(el)el.onclick=associateObjWithEvent(this,doOnClick);el.onmouseover=associateObjWithEvent(this,doMouseOver);el.onmouseout=associateObjWithEvent(this,doMouseOut);HtmlEle.prototype.doOnClick=function(element)alert(element);HtmlEle.prototype.doMouseOver=function(element)alert(鼠标移动到元素+element.id+上了);HtmlEle.prototype.doMouseOut=function(element)alert(鼠标移出了元素+element.id);var div=new HtmlEle(closuretest);/使用构造函数创建HtmlEle对象,内部函数将作为DOM 元素的事件处理器,this指向obj,即传入的dom元素,为HtmlEle对象扩展3个属性,每个属性的值都是函数类型,3.2 闭包之间的交互,当存在多个内部函数时,可能会出现意料之外的闭包。此时,假设多个内部函数(闭包)引用了同一个外部函数的变量,则内部函数共享同一个封闭环境。如果重新创建一个全局变量引用内部函数,则变量的值也重新初始化,function outerFunc()var outerVar=0;function innerFunc1()document.writeln(+outerVar);function innerFunc2()outerVar+=5;document.writeln(,+outerVar+);/返回一个具有两个属性的对象 return innerFunc1:innerFunc1,innerFunc2:innerFunc2;var globalVar=outerFunc();globalVar.innerFunc1();globalVar.innerFunc2();globalVar=outerFunc();globalVar.innerFunc1();globalVar.innerFunc2();,小结3,闭包是什么?举例说明闭包有哪些作用,4.JavaScript处理JSON格式数据,4.1 JSON是什么?,JSON即javascript对象标记,是一种轻量级的数据交换格式,JSON的优势:同XML或HTML相比,JSON 更简单灵活 JSON是基于纯文本的数据格式,便于在网络上传入和解析JSON的数据格式简单,但却可以传输任何类型的数据 JSON是JavaScript原生格式,在JavaScript中处理JSON数据不需要任何特殊的 API 或工具包,订单编号:OD-00001,订单日期:2010-1-23,订货人:Tom,订单详细:商品编号:SP-20100123,数量:5,单价:120,总价:600,商品编号:SP-20100124,数量:50,单价:100,总价:5000,JSON数据格式:可以是任何类型的数据,包括JavaScript对象和数组,4.2 JavaScript处理JSON数据,JavaScript访问JSON数据直接可以通过“.”运算符访问JSON数据的属性,也可以直接使用“=”为属性赋值,function handleJSON()var user=name:Michael,address:city:Beijing,street:Chaoyang Road,postcode:100025;document.write(user.name=+user.name);document.write(user.address.city=+user.address.city);function showJSON()var user=username:Tom,age:20,info:tel:123456,cellphone:98765,address:city:beijing,postcode:222333,city:newyork,postcode:555666 with(document)writeln(user.username=+user.username);writeln(user.age=+user.age);writeln(user.info.cellphone=+user.info.cellphone);writeln(user.address0.city=+user.address0.city);/address是数组 writeln(user.address0.postcode=+user.address0.postcode);user.username=Jack;document.writeln(user对象的username属性被重新赋值,user.username=+user.username);handleJSON();showJSON();,取JSON对象的属性值,为属性赋值,JavaScript处理JSON数据,使用“json2.js”文件中stringify()方法将JSON对象转换为JSON字符串使用“json2.js”文件中parse()方法将JSON格式的字符串转换为JSON数据对象使用JavaScript的eval()方法将普通字符串转换为JSON数据对象,/声明普通字符串 var normalstring=persons:name:jordan,sex:m,age:40,name:bryant,sex:m,age:28;/声明JSON格式的字符串 var jsontext=persons:name:jordan,sex:m,age:40,name:bryant,sex:m,age:28;var myjson=eval(normalstring);with(document)writeln(转换后的JSON对象:+myjson);document.writeln(myjson0.name=+myjson0.name);var text=JSON.stringify(myjson);document.writeln(转换后的json文本:+text);var myData=JSON.parse(jsontext);document.writeln(转换后的JSON对象:+myData);document.writeln(myjson1.name=+myjson1.name);,小结4,JSON有哪些优势?JavaScript如何解析JSON格式的数据?如何把JSON格式的数据对象转换为字符串?,本章总结,JavaScript创建数组有两种方式使用创建使用new关键字创建数组对象Array()在JavaScript中可以创建命名函数、匿名函数和内部函数JavaScript中函数的参数长度是不固定的,实际参数可以与形式参数的个数不同JavaScript中对象就是无序属性的集合,对象的属性可以是任何类型的数据JavaScript常用的内置对象Global对象时顶级对象,在浏览器中,window对象就是Global对象Object对象时所有对象Function对象的构造函数可以创建函数对象Object对象是所有对象的基础,任何其他对象都是从Object对象扩展而来当一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。闭包可以读取函数内部的变量,让这些变量的值始终保持在内存中JSON是一种基于文本格式的轻量级对象,使用JavaScript处理JSON数据简单、方便,