首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

shim是应该抛错误还是应该fail silently

2012-10-30 
shim是应该抛异常还是应该fail silently?玉伯发布了es5-safe模块,这是一个有一点类似es5-shim的项目。个人

shim是应该抛异常还是应该fail silently?
玉伯发布了es5-safe模块,这是一个有一点类似es5-shim的项目。

个人认为玉伯这个模块对于准备从ES3过渡到ES5的前端开发者来说是一个稳妥的选择。在本文的最后部分会进一步说明。下面的部分是理论性的探讨,无兴趣者可略过了。



es5-safe的缘起,是玉伯主张一个不太一样的策略,即“用 throw error 的策略来代替 fail silently”。

玉伯在《扩展原生对象与 es5-safe 模块》一文中写道:
obj.bar = 2;var foo = obj.foo;var bar = obj.bar;if(foo !== 2) foo = 2;if(bar === undefined) alert('fu*ck');
这样会让使用者发狂的。

要么完美支持,要么抛出异常,灰色地带很诱人但实在危险。基础类库的 fail silently,要做到无害,无隐患(ES5 的这些方法里好像没有)很难。

2 楼 hax 2011-08-12   @lifesinger

你的例子当中,create一个带有get accessor的对象。如我文中所述,es5-shim对此也是抛出异常的,尽管其文档说是fail silently。因此在这点上已经可以起到提示开发者的作用。

而我说seal这个防御性调用,通常fail silently是可接受的,这个前提是我们使用ES5 strict模式(也许我文中还不够强调此点)。

在strict模式下, obj.bar = 2 会扔出TypeError。因此不用到IE6里我们就已经发现错误了。

因此也不会有你所说的类库使用者调整代码的必要了。


唯一可能导致错误的情形是代码依赖于此种异常,如:

try {
   obj.bar = 2
} catch(e) {
   // do sth...
}

我很难想到一个合理的case,需要这样的代码。

即使真的有这样的需求,也很容易将捕捉异常改为测试方法:

if (Object.seal(obj) {
   // do sth...
}


总之,es5-shim的目标并非要“完美”支持,而是让在ES5环境里可以跑的程序也能不做改动跑在前es5环境中。

凡是真的无法运行在IE6中的,那在IE6中扔出异常是应该的。例如get/set。而seal这类防御性代码,在正常情形下,是不会影响代码逻辑的,因此fail silently是可接受的。当然我们可能犯错,所以我建议始终用strict模式,这样在FF调试时你已经能发现错误(比如对sealed对象的修改),这样这个bug就不会留到IE6中去。

如果开发者故意选择了non-strict模式,或者其代码依赖于对防御性代码的功能性运用(如利用try/catch),那他应该明确了解他在干什么,并承担后果,呵呵。

【也许我应将本文改写为《es5-shim最佳实践》?呵呵】




3 楼 hax 2011-08-12   另外,如果遵循了我所说的采用strict模式,并且不做“功能性的利用防御性方法”这样奇怪的事情,那么要兼容IE6所要记住的东西其实还挺少的。就是以下两点:

1. 不要用get/set
2. 不要依赖enumerable

其中第二点在未来可能会得到解决。


其他的坑基本上在strict模式下已经都填平了。不会漏到IE6那里去。


【当然坑总是有的,如lifesinger原文中提到的array literal initialization的坑,不过这种坑不是es5-shim或es5-safe可以解决的。】 4 楼 lifesinger 2011-08-12   明白了,我测试时忘了打开 strict 模式
就怕这种忘了导致的 bug, 特别是大团队合作时
我还是继续 es5-safe 先
等 ie6-7 可以不考虑了,再切换到 es5-shim, ie8 下貌似绝大部分都可以“安全”实现 5 楼 hax 2011-08-15   lifesinger 写道明白了,我测试时忘了打开 strict 模式
就怕这种忘了导致的 bug, 特别是大团队合作时


确实,这里存在这种可能。除了“忘记”之外,还有一点就是目前浏览器的stable版本支持strict的并不多,如chrome/safari目前的stable版本尚不支持strict模式。NodeJS stable版本(0.4.x)也不支持strict模式。

所以目前要测试时,除了加上"use strict"外,还必须是在以下环境:

FF 4+
Chrome/Safari的beta版
NodeJS 0.5+

热点排行