本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。
错误处理对于web应用开发至关重要,任何javascript错误都有可能会导致网页无法使用,因此作为开发人员,必须要及时处理有可能出现的错误;
从IE4.0之后,几乎所有的浏览器都包含了一些基本的错误处理功能,但并没有统一,后来,由ECMAscript添加了异常处理机制,也就是try…catch…finally结构以及throw操作;
错误处理的重要性: 好的错误处理技术可以让脚本的开发、调试和部署更加流畅,能对代码进行更好的控制;另外,JS缺乏标准的开发环境;
错误类型:
语法错误(syntax error):也称为解析错误,发生在传统编程语言的编译解释时;发生语法错误时,就会发生阻塞,也就是不能继续执行代码,但只是同一个线程中的代码会受影响,其他线程中的代码不受影响;
// Uncaught SyntaxError: Invalid or unexpected token// 未捕获的语法错误:无效或意外的标记document.write("zeronetwork;运行时错误(Runtime error):也称为exception异常, 其发生在编译期/解释期后,此时,问题并不出现在代码的语法上,而是在尝试完成一个非法的操作;
<input type="button" value="单击" onclick="handleClick()" /><script>// Uncaught ReferenceError: openMy is not defined// 未捕获的引用错误:未定义openMyfunction handleClick(){ openMy();}</script>错误报告:
因为每个浏览器都有自己的内置Javascript解释程序,所以每种浏览器报告错误的方式都不同;有些是弹出错误信息,有些是把信息打印在控制台中;
IE(windows): 默认情况下,会弹出包含错误细节的对话框,并询问是否继续执行页面上的脚本;如果浏览器有调试器(如:Microsoft Script Debugger) ,此对话框会提供一个是调试还是忽略的选项;如果在IE设置中取消了”显示错误”,那么会在页面左下角显示一个黄色的图标;
注:如果JS代码就在HTML里,显示错误行是正确的,如果是外部的JS文件,则行号往往差一行,如第5行则为第4行;
Mozilla(所有平台): 在控制台中打印错误信息,并发出警告;其会报告三种类型的消息:错误、严格警告和消息等的;
Safari (MacOS):是对JavaScript错误和调试的支持最差,默认情况下,它对终端用户不提供任何javascript错误报告;
错误处理:
Javascript提供了两种处理错误的方式:
BOM包含一个onerror事件处理函数,该函数通常被绑定在window对象或image对象上;ECMAscript定义了try…catch结构来处理异常;onerror事件处理函数:
window对象的onerror属性是一个事件处理程序,页面上出现异常时,error事件便在window对象上触发,并把错误消息输出到Javascript控制台上,这种方式也称为全局错误捕获;如:
window.onload = function(){ show(); // 在onload事件中调用了一个不存在的函数}window.onerror = function(){ alert("出现错误"); return true;}获取错误信息:
window.onerror事件处理程序在调用时可以传5个参数,由这5个参数可以获取详细的错误信息;
message:错误信息,描述错误的一条消息;URL:引发错误的Javascript所在的文档的URL;line:文档中发生错误的行数;column:发生错误的列数;error:错误对象,这个error也称为全局错误对象;window.onerror = function(sMessage, sUrl, sLine, sColumn, error){console.log("Error:" + sMessage + " URL:" + sUrl + " Line:" + sLine + " Column:" + sColumn);console.log(error); return true;}onerror处理程序的返回值:
如果返回true,则阻止执行默认的事件处理程序,也就是将通知浏览器,事件处理程序已经处理了错误,不需要其他操作,反之会显示错误消息;
某些元素也支持onerror; 但其处理函数没有任何关于error信息的参数,如:
document.images[0].onerror = function(event){console.log(event); // Eventconsole.log(event.type); // error}这里的event参数是一个类型为Event事件对象,其存储的信息除了type返回了error,并没有其他和错误相关的信息;
全局错误处理window.onerror通常不能恢复脚本继续执行,但会给开发者发送错误信息;
window.onerror = function(error){ console.log(error);}show();console.log("中止,不会被执行");window.onload = function(){ console.log("也不会被执行");}可以是简单的打印,也可以把错误保存到日志记录里;
window.onerror就是绑定在window对象的error事件,也可以使用标准的添加事件侦听的方式window.addEventListener(eventtype, handler),其需要两个参数,eventtype为事件类型,在此为error,handler是事件处理函数,其需要一个参数event,一个ErrorEvent类型的对象,其保存着有关事件和错误的所有信息,如:
window.addEventListener("error", function(event){ console.log(event); // ErrorEvent console.log(event.error); // Error对象 console.log(event.error.name); console.log(event.error.message); console.log(event.error.stack); console.log(event.lineno); // 行 console.log(event.colno); // 列 console.log(event.filename);});在实际的开发中,这两种方式都会被使用,只不过addEventListener有定的兼容必问题,所以要兼顾所有的浏览器且不太关注事件对象本身的话,就使用window.onerror;
当加载自不同域的脚本中发生语法错误时,为避免信息泄露,语法错误的细节将不会报告,只会返回简单的"Script error.";
<script>window.onerror = function(msg, url, lineNo, columnNo, error){ console.log(msg); // Script error console.log(url); // "" console.log(lineNo); // 0 console.log(columnNo); // 0 console.log(error); // null}</script><script src="https://www.zeronetwork.cn/demo/demo.js"></script>可以针对同域和不同域的错误分开处理,如:
<script>window.onerror = function(msg, url, lineNo, columnNo, error){ var str_error = msg.toLowerCase(); var sub_string = "script error"; if(str_error.indexOf(sub_string) > -1) alert("脚本发生错误,详情请在控制台查看"); else{ var message = [ '消息:' + msg, 'URL:' + url, '行:' + lineNo, '列:' + columnNo, '错误对象:' + error ].join(" - "); alert(message); }}show();</script><script src="https://www.zeronetwork.cn/demo/demo.js"></script>从上在的执行结果来看,error事件执行了两次,原因是使用了两个script,也就是当一个script有错误发生时,它只会阻止当前的script块,而不会阻止其他的script块;如:
<script>show(); // 会捕获console.log("不会被执行");myshow(); // 不会捕获</script><script src="https://www.zeronetwork.cn/demo/demo.js"></script><script>console.log("执行了");demo(); // 会捕获console.log("不会被执行");</script>body元素的onerror特性,也可以充当事件处理函数,如:
<body onerror="alert('出现了错误');return true;">注意,先注释掉window.onerror等代码;
此时,可以直接使用event、source、lineno、colno、error等属性;
<body onerror="alert(event + '\n' + source + '\n' + lineno + '\n' + colno + '\n' + error);return true;">当然了,也可以为body绑定error事件,此时各属性,必须明确指定,如:
document.body.onerror = function(msg, url,lineno,colno,error){ alert(msg + '\n' + url + '\n' + lineno + '\n' + colno + '\n' + error); return true;}try-catch语句:
try语句中为期待正常执行的代码块,当在try语句中发生错误,其余代码会中止执行,catch语句就处理该错误,如果没有错误,就跳过catch语句;try和catch必须成对出现;
try{ //code [break]}catch([exception]){ //code}[finally]{ //code}// 如try { show(); alert("不能执行");} catch (error) { alert("出现一个错误:" + error);} finally{ alert("管你呢");}try语句块内的错误只会中止try语句块中发生错误之后的逻辑代码,并不会中止整个脚本的运行;执行try-catch语句,必须是运行时,运行时错误,也被称为异常;try-catch语句中指定只能有一个catch子句;try-catch语句适合处理无法预知、无法控制的错误;finally常被用于无论结果是否有异常,都要执行的代码,如:
try{ alert("try"); show(); alert("no exec");}catch(error){ alert("catch");}finally{ alert("finally");}alert("continute");代码执行的两条路径:如果没有异常,执行路径为:try->finally,反之为:try的部分->catch->finally;
一般用于关闭打开的链接和释放资源;
var connection = {open: function(){},close: function(){},send: function(data){}}// var data = "大师哥王唯"; // 注释这一行,让它产生异常connection.open();try{ connection.send(data);}catch(exception){ console.log("出现一个错误");}finally{ connection.close(); console.log("关闭了");}还有一个典型的应用,读写文件,如:
function openFile(){};function writeFile(data){};function closeFile(){};openFile();try{ writeFile();}catch(error){ console.log(error);}finally{ closeFile();}在try-catch-finally语句块中的变量是全局变量:
try{ var name = "王唯"; show(); var city = "蚌埠";}catch(error){ var age = 18; console.log(name);}finally{ var sex = "男"; console.log(name); console.log(age);}console.log(name);console.log(city);console.log(age);console.log(sex);try-catch-finally与return:
如果直接在try-catch-finally语句块中执行return,会抛出异常,如:
try { console.log("try"); // return; // Illegal return statement 非法返回语句 console.log("try agin");} catch (error) { console.log(error); // return; // Illegal return statement}finally{ console.log("finally"); // return; // Illegal return statement}如:
function foo(){ try { console.log("try"); return 1; show(); console.log("try agin"); } catch (error) { console.log(error); return 2; }finally{ console.log("finally"); return 3; }}console.log(foo()); // 3try-finally:
没有catch从句,只有try-finally也可以,目的是,只确保执行开始和最终的过程,而不处理错误,如:
try{ console.log("try"); show();}finally{ console.log("finally"); // 会执行}console.log("over"); // 不会执行,已中止但此时,还是会抛出异常的,但此时,会在执行完finally后中止执行,并会查找外部的catch语句;
嵌套try-catch语句:
在catch子句中,也有可能会发生错误,所以就可以使用嵌套的try-catch语句,如:
try { show(); console.log("不能执行");} catch (error) { console.log("出现一个错误:" + error); try { var arr = new Array(10000000000000000); arr.push(error); } catch (error) { console.log("又出现了一个错误:" + error); }} finally{ console.log("管你呢");}也可以在try中嵌套try-catch-finally语句,如:
try{ try{ console.log("try"); show(); }catch(error){ console.log("error"); }finally{ console.log("finally"); }}catch(error){ console.log(error);}一个比较典型的应用,就是处理json数据,如:
// var json = '{"name":"wangwei", "age": 18, "sex": "男"}';var json = '{bad json}'; // Uncaught SyntaxErrorvar data = JSON.parse(json);console.log(data.name);console.log(data.age);console.log(data.sex);一量json数据发生错误,整个应用都会崩溃,所以应该使用try-catch,如:
<div id="msg">您的信息:</div><script>window.onload = function(){ var msg = document.getElementById("msg"); try{ // var json = '{"name":"王唯", "age": 18, "sex": "男"}'; var json = '{bad json}'; // Uncaught SyntaxError var data = JSON.parse(json); msg.innerHTML += "姓名:" + data.name + ",年龄:" + data.age + ",性别:" + data.sex; }catch(error){ msg.innerHTML = "开小差了,找不到你的信息"; }}</script>当使用了try-catch语句,就不会将错误提交给浏览器,也就不会触发error事件,如:
window.onerror = function(error){ console.log(error); // 不会触发}try{ show();}catch(error){ console.log(error);}Error错误对象:
在catch中会捕获一个Error错误对象;该对象在Javascript解析或运行时,一旦发生错误,引擎就会抛出这个对象;如果没有相关联的try-catch捕获该对象,就由浏览器输出这个对象;
// ...console.log("错误:" + error + " name:" + error.name + " message:" + error.message);也可以通过Error的构造器创建一个错误对象,这个Error对象也可用于用户自定义的异常;语法:new Error([message[, filename[, lineNumber]]]);
message:可选,错误描述信息;fileName:可选,非标准,被创建的Error对象的fileName属性值,默认是调用Error构造器代码所在的文件的名字; 但大部分浏览器没有实现;lineNumber:可选,非标准,被创建的Error对象的lineNumber属性值,默认是调用Error构造器代码所在的文件的行号;但大部分浏览器没有实现;实例化Error对象,也可以不使用new关键字,如:
var error = new Error("自定义错误对象");var error = Error("不使用new");console.log(error);console.log(error.name); // Errorconsole.log(error.message); // 自定义错误对象Error错误对象属性:
name:表示错误类型的字符串;message:实际的错误信息;Error类还有6个子类,其可以通过错误对象的name属性返回具体异常类的名称:
EvalError:错误发生在eval()函数中;RangeError:数值超出javascript可表示的范围;;ReferenceError:使用了非法或不能识别的引用;SyntaxError:发生了语法错误;TypeError:操作数的类型不是预期所需的;URIError:在encodeURI()或decodeURI()函数中发生了错误;// EvalErrortry{ throw new EvalError("Eval异常");}catch(error){ console.log(error); console.log(error instanceof EvalError); // true console.log(error.name); // EvalError console.log(error.message); // Eval异常}// RangeErrorvar num = 1;try{ num.toPrecision(500); // [prɪˈsɪʒn] 精度}catch(error){ console.log(error); }// ReferenceErrorvar x;try { x = y + 1;} catch (error) { console.log(error);}// SyntaxErrortry{ eval("alert('wangwei)");}catch(error){ console.log(error);}// TypeErrorvar num = 1;try{ num.toUpperCase(); // 无法将数字转为大写}catch(error){ console.log(error);}// URIError (malformed [ˌmælˈfɔːmd]格式不正确,畸形的)try{ decodeURI("%%%"); // 使用了非法字符}catch(error){ console.log(error);}Error对象的message属性是浏览器生成的用于表示错误描述的信息,因为这个属性是特定于浏览器的,所以不同的浏览器上可能产生不同的错误信息,如:
try { eval("a ++ b"); show(); console.log("执行了吗?");} catch (error) { // SyntaxError:Unexpected identifier或 // SyntaxError:unexpected token: identifier console.log(error.name + ":" + error.message);}使用name属性判断错误类型:
try { eval("a++b");} catch (error) { console.log(error instanceof SyntaxError); // true if(error.name == "SyntaxError") console.log(error.name + ":" + error.message); else console.log("未知错误:" + error.message);}抛出异常:
throw语句的作用是手动中断程序执行,抛出一个错误,一般用于有目的的抛出异常,也就是允许开发者可以创建自定义错误;
throw可以抛出任何类型的值,也就是说,它的参数可以是任何值;语法:throw error_object;error_object可以是字符串、数字、布尔或对象;
throw "出现一个错误";throw 50666;throw true;throw new Object();throw { toString:function(){ return 'Error!'; }}function getRectArea(width, height){ if(isNaN(width) || isNaN(height)) throw '参数应该是number类型'; return width * height;}getRectArea("wangwei",10);对于Javascript引擎来说,只要遇到throw语句,程序就会终止;
也可以抛出一个Error错误对象;Error对象的构造函数只有一个参数,
throw new Error("请再次尝试");其他Error子类对象也可以抛出:
throw new SyntaxError("...");throw new TypeError("...");throw new RangeError("...");throw new EvalError("...");throw new URIError("...");throw new ReferenceError("...");对于Error类和其子类来说,错误对象的name就是其构造函数的名称,message是其构造函数的参数;
当抛出异常后,throw之后的语句将不会执行,并跳到相关联的catch语句中进行处理,如:
<h1>请输入18-99之间的数字</h1><input id="txtInput" type="text" /><button id="btn">确定</button><p id="msg"></p><script>function myFun(){ var msg,x; msg = document.getElementById("msg"); msg.innerHTML = ""; x = document.getElementById("txtInput").value; try{ if(x == "") throw "空的"; if(isNaN(x)) throw "不是数字"; x = Number(x); if(x < 18) throw "太小"; if(x > 99) throw "太大"; msg.innerHTML = "输入的值正确:" + String(x); } catch(error){ msg.innerHTML = "输入的值不正确:" + error; }}var btn = document.getElementById("btn");btn.onclick = myFun;</script>也可以在某个语句块的外部捕获throw异常,如:
function sum(a,b){ if(arguments.length < 2) throw new Error("需要两个参数"); else return a + b;}try{ console.log(sum(18));}catch(error){ // Error:需要两个参数 console.log(error.name + ":" + error.message);}可以通过instanceof判断异常的类型来特定处理某一类的异常,例如可以区分浏览器抛出的异常和开发人员抛出的异常,如:
function sum(a,b){ if(arguments.length < 2) throw new Error("需要两个参数"); if(isNaN(a) || isNaN(b)) throw "参数是不是Number类型"; return a + b;}try{ console.log(sum(18,12));}catch(error){ if(error instanceof SyntaxError) console.log("语法错误:" + error.name + ":" + error.message); else if(error instanceof Error) console.log(error.name + ":" + error.message); else console.log(error);}注:判断Error类型要放到if的最后一个条件;
即使在catch语句中,还可以根据实际情况,再次抛出异常,此时,其可以被外部的try-catch语句块捕获(如果存在的话);
当发生异常时,代码会立即停止,仅当有try-catch语句捕获到异常时,代码才会继续执行;其背后运行的原理是,当发生异常,JavaScript解释器会立即停止执行的逻辑,并跳转到就近的try-catch异常处理程序,如果发生异常的代码块中没有相关联的catch从句,解释器会检查更高层的闭合代码块,看它是否有相关联的异常处理程序,以此类推,直到找到一个异常处理程序为止;如果发生异常的函数中没有处理它的try-catch语句,异常将向上传播到调用该函数的代码,如此,异常就会沿着Javascript的语法结构或调用栈向上传播;如果没有找到任何异常处理程序,JavaScript将把异常当成程序错误来处理,并通过浏览器报告给用户;
自定义错误类型:
可以基于Error类来创建自定义的错误类型,此时可以使用throw抛出自定义的异常类,或通过instanceof来检查这个异常类的类型,新类型需要实现name和message属性;
function CustomError(message){ this.name = "CustomError"; this.message = message || 'Default Message'; this.stack = (new Error()).stack;}// CustomError.prototype = new Error();// 或者CustomError.prototype = Object.create(Error.prototype);CustomError.prototype.constructor = CustomError;try{ var name = "jingjing"; if(name !== "wangwei") throw new CustomError("自定义的错误类型");}catch(error){ console.log(error.message);}小示例:
function UserException(message){ this.name = "UserException"; this.message = message;}function getMothName(m){ m = m - 1; // 调整月份数字到数组索引(1=Jan,12=Dec) var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; if(months[m] != undefined) return months[m]; else throw new UserException("Invalid Month No");}try{ var myMonth = 15; var monthName = getMothName(myMonth);}catch(error){ var monthName = "未知"; console.log(error.name + ":" + error.message);}小示例:验证电话号码,如:
function Telephone(num){ num = String(num); var pattern = /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/; if(pattern.test(num)){ this.value = num.match(pattern)[0]; this.valueOf = function(){ return this.value; }; this.toString = function(){ return String(this.value); } }else{ throw new TelephoneFormatException(num); }}function TelephoneFormatException(value){ this.name = "TelephoneFormatException"; this.message = "电话号码格式不正确"; this.value = value; this.toString = function(){ return this.value + ":" + this.message; }}// 应用var TELEPHONE_INVALID = -1;var TELEPHONE_UNKNOWN_ERROR = -2;function verifyTelephone(num){ try{ num = new Telephone(num); }catch(error){ if(error instanceof TelephoneFormatException) return TELEPHONE_INVALID; else return TELEPHONE_UNKNOWN_ERROR; } return num.toString();}console.log(verifyTelephone("010-66668888"));console.log(verifyTelephone("13812345678"));console.log(verifyTelephone("138123456")); // -1console.log(verifyTelephone("wangwei")); // -1常见错误:
由于javaScript是松散类型的,也不会验证函数的参数,因此错误只会在运行时出现;一般来说,需要关注三种错误:类型转换错误、数据类型错误、通信错误;
类型转换错误:
一般发生在使用某个操作符,或者使用其他可能自动转换值的数据类型的语言结构时;
function output(str1,str2,str3){ var result = str1 + str2; if(str3) result += str3; return result;}console.log(output(1,2,3));console.log(output(1,2));console.log(output(1,2,0));console.log(output(1,2,"wangwei"));这就是一个非常典型的与期望不一致的方式;
数据类型错误:
在流控制语句中使用非布尔值,是极为常见的一个错误来源,为避免此类错误,就要做到在条件比较时确定传入的是布尔值,例如,把if语句改成:if(typeof str3 == 'number');
所以在使用某个变量或对象时,一定要适当地检查它的数据类型,如:
function reverseSort(values){ // if(values){ // values.sort(); // values.reverse(); // } if(arguments.length > 0){ if(!Array.isArray(values)) return []; else{ values.sort(); values.reverse(); return values; } } return [];}var arr = [3,2,6,9,4];// var arr = 100; // Uncaught TypeError: values.sort is not a functionconsole.log(reverseSort(arr));另一个常见的错误就是将参数与null值进行比较。与null进行比较只能确保相应的值不是null和undefined。要确保传入的值有效,仅检测null值是不够的;
function reverseSort(values){ // if(values != null){ // 任何非数组值都会导致错误 if(values instanceof Array) // 非数组值被忽略 values.sort(); values.reverse(); } return values;}var arr = [3,2,6,9,4];// var arr = 100; // Uncaught TypeError: values.sort is not a functionconsole.log(reverseSort(arr));// 或function reverseSort(values, fun){ if(values instanceof Array){ if(fun != null && typeof fun === "function") values.sort(fun); else values.sort(); } return values;}var arr = [3,2,6,9,4];console.log(reverseSort(arr, function(a,b){ return a > b ? -1 : 1;}));通信错误:最典型的就是Ajax应用,用其可以动态加载信息,但是,javascript与服务器之间的任何一次通信,都有可能会产生错误;
调试技巧:
使用警告框: 这是最简单、流行的方式,如:
function test(){ alert("函数内"); var iNum1 = 5, iNum2 = 10; alert(iNum1); var iResult = iNum1 + iNum2; alert(iResult);}test();抛出自定义错误:
function assert(bCondition, sErrorMessage){ if(!bCondition) throw new Error(sErrorMessage);}function divide(iNum1, iNum2){ assert(arguments.length == 2, "divide需要两个参数"); assert((!isNaN(iNum1) && !isNaN(iNum2)), "需要Number类型"); return iNum1 / iNum2;}console.log(divide(10,2));console.log(divide(10,"c")); // 异常// 或try{ console.log(divide(10,"c"));}catch(error){ console.log(error.name + ":" + error.message);}Javascript校验器:
jslint的主要目的是指出不合规范的js语法和可能的语法错误,包括一些不良代码;官网:http://www.jslint.com/
如以下,会给出警告:
语句未使用块标记;一行的结尾未以分号结束;用var声明一个已在使用的变量;with语句;调试器:
Javascript自身不具备调试器,但目前所有的浏览器可以使用自身的调试器;
IE调试:
启用IE的调试功能:
菜单“工具”|“Internet选项”命令,打开“Internet选项”对话框,在“高级”选项卡中,找到两个“禁用脚本调试”复选框并取消;开始调试,调试的主要工作是反复地跟踪代码,找出错误并修正;
设置断点:
在调试程序窗口中,将光标移动到需要添加断点的行上,按一次F9键或单击,当前行的背景色变为红色,并且在窗口左边界上标上红色的圆点,当程序运行到断点时就会暂停;
运行调试:
单击继续或按F5进行逐步运行调试;F10步进、F11步入,都可以继续向下执行;将鼠标移动到变量名上时,会显示变量当前时刻的值;或者在右侧的“监视”窗格中可以观察该变量的值;点击变量信息框中的变量值或右侧“监视”空格中的变量值可以修改变量的当前值;更多的调试操作:查看调用关系、监视特定变量的值等;
// 示例var balance = 200.0; //var willPay = 20.0;function pay(_balance, _pay){ return _balance - _pay;}function showBalance(){ debugger; var blnc = pay(balance,willPay); alert("当前余额:" + blnc);}showBalance();日志输出:
程序运行时,有些中间数据需要记录,以便检查程序运行的状态;对于JavaScript记录中间数据通常是以日志的形式记录需要记录的数据,再发送到服务器上保存起来;日志记录的内容可以是任意的信息,根据开发者的需要而定;
function Logger(){ // 日志对象构造函数 function record(_serial, _message){ // 记录对象构造函数 this.serial = _serial; // 记录编号 this.message = _message; // 记录信息 this.date = new Date(); // 记录时间 } this.recordList = new Array(); // 创建数组容器 this.index = 0; // 记录索引 this.log = function(info){ // “添加日志”函数 var newLog = new record(++this.index, info); this.recordList.push(newLog); } this.showLog = function(_mode){ // 显示记录信息 var info = ""; // 分析出的日志信息文本 for(n in this.recordList){ // 逐一分析记录数组 if(_mode == 0){ // 显示模式0 info += "<li>" + this.recordList[n].serial + "(" + this.recordList[n].date.toLocaleString() + "):" + this.recordList[n].message + "</li>";// 格式化信息 if(n == (this.recordList.length - 1)){ document.write(info); // 在当前文档输出 } }else if(_mode == 1){ // 显示模式1 info += "#" + this.recordList[n].serial + "(" + this.recordList[n].date.toLocaleString() + "):" + this.recordList[n].message + "\n"; // 格式化信息 if(n == (this.recordList.length - 1)){ alert(info); // 以对话框的形式输出 } } } return info; // 将格式化后的信息返回给调用 }}// 应用var g_log = new Logger(); // 创建一个全局日志对象var balance = 200.0; // 当余额g_log.log( "balance:" + balance ); // 上一步操作后,添加日志var willPay = 20.0; // 当前该付金额g_log.log( "willPay:" + willPay ); function pay( _balance, _pay ){ // 付账动作 g_log.log( "_balance:" + _balance ); g_log.log( "_pay:" + _pay ); return _balance - _pay; // 从余额中减去该付的数额}function ShowBalance(){ var blnc = pay( balance, willPay ); // 付账 g_log.log( "blnc:" + blnc ); document.write( "当前余额:" + blnc ); // 输出余额}ShowBalance(); // 显示余额g_log.showLog(0); // 输出日志信息
京公网安备11000000000001号
京ICP备11000001号
还没有评论,来说两句吧...