总的来说,基本类型的值使用 typeof 检测,而对象的值使用 instanceof 来检测。特别是面向公众的 API,一定要执行类型检查,以确保函数始终能够正常执行。
4.3 通信错误JavaScript 与服务器之间的任何一次通信,就有可能会产生错误。
一种通信错误是发送了不正确的 URL 格式数据。一般是没有使用 encodeURIComponent() 对数据进行编码,可以使用这里的函数来处理查询字符串:
/** * 添加查询字符串 * @param url URL * @param name 参数名 * @param value 参数值 * @returns {*} */ function addQueryStringArg(url, name, value) { if (url.indexOf("?") == -1) { url += "?"; } else { url += "&"; } url += encodeURIComponent(name) + "=" + encodeURIComponent(value); return url; }
尽量使用这个函数,就可以确保编码正确。
5 区分致命错误与非致命错误非致命错误可以根据以下列出的一个或多个条件来确定:
不影响用户的主要任务;
只影响页面的一部分;
可以恢复;
重复操作可以消除错误。
而致命错误也可以根据以下列出的一个或多个条件来确定:
无法继续执行;
影响到了用户的主要操作;
导致其他连带的错误。
如果发生了致命错误,要立即发送消息通知用户,告诉他们无法再继续操作咯。如果必须刷新页面才会恢复,也必须通知用户,并提供了可刷新页面的按钮。
比如,在大型网站中,可能有多个互不依赖的模块,它们是类似这样初始化的:
for (var i=0, len=mods.length; i<len; i++){ mods[i].init(); }
这样做的问题是,如果有一个模块发生错误,那么就会导致后续的其它模块无法被初始化,从而导致致命的错误!我们这样改造下,让致命的错误变成非致命的错误:
for (var i=0, len=mods.length; i<len; i++){ try{ mods[i].init(); } catch (ex){ ... } }
6 把错误记录到服务器建议集中保存错误日志,这样可以方便后续查找错误的原因。所以我们可以把 JavaScript 错误发送给服务器,让服务器保存起来。这样把前后端的错误集中起来管理,就可以很方便地对数据进行分析咯O(∩_∩)O~
首先先在服务器上创建一个接口,用于接收页面发送的错误数据:
/** * 记录 JavaScript 错误 * @param sev 严重程度,比如:nonfatal * @param msg 错误消息 */ function logError(sev,msg){ var img=new Image(); img.src="log.action?sev="+encodeURIComponent(sev)+"&msg="+encodeURIComponent(msg); }
使用 Image 对象来发送请求,有这些好处:
所有的浏览器都支持 Image 对象,包含那些不支持 XMLHttpRequest 对象的浏览器。
可以避免跨域限制。比如可以使用一台日志服务器专门接收多台 web 服务器抛出的错误。
只要是使用了 try-catch 语句,就要把错误记录到日志中:
for (var i=0, len=mods.length; i<len; i++){ try{ mods[i].init(); } catch (ex){ logError("nonfatal","模块初始化失败:"+ex.message); } }
第二个参数是上下文信息以及 JavaScript 的错误消息,带上上下文信息可以方便分析导致错误的真正原因。