JavaScript中的断言
广泛阅读JavaScript中的各种断言框架。是否存在任何事实上/最常见的“标准”库/框架?选择一个时,哪些点最值得注意JavaScript中的断言,javascript,assert,assertions,Javascript,Assert,Assertions,广泛阅读JavaScript中的各种断言框架。是否存在任何事实上/最常见的“标准”库/框架?选择一个时,哪些点最值得注意 在生产模式下,我能想到的(唯一)要求是接近零的性能开销。两种可能的解决方案: 让构建发布脚本删除断言行 或 让构建脚本重写Assert函数,使它只是一个空函数。这样做的缺点是,如果断言调用中包含逻辑[aka assert(x>100,“foo”)],那么该逻辑[x>100]仍将运行 以下是我使用的: 在编写代码时,我有initDevMode();在我正在处理的文件的顶部,当我
在生产模式下,我能想到的(唯一)要求是接近零的性能开销。两种可能的解决方案: 让构建发布脚本删除断言行 或 让构建脚本重写Assert函数,使它只是一个空函数。这样做的缺点是,如果断言调用中包含逻辑[aka assert(x>100,“foo”)],那么该逻辑[x>100]仍将运行 以下是我使用的: 在编写代码时,我有initDevMode();在我正在处理的文件的顶部,当我准备发布到生产环境时,我只需删除该行,所有断言都会转到一个空函数
/**
* Log a message to console:
* either use jquery's console.error
* or a thrown exception.
*
* call initDevMode(); before use to activate
* use with:
* assert(<condition>, "message");
* eg: assert(1 != 1, "uh oh!");
*
* Log errors with:
* errorLog(message);
* eg: errorLog(xhr.status);
*/
assert = function(test, msg) { }
errorLog =function(msg) { }
initDevMode = function() {
assert = function(test, msg) {
msg = msg || "(no error message)";
if(!test) {
try {
throw Error();
} catch(e) {
var foo = e;
var lines = e.stack.split('\n');
for(i in lines) {
if(i > 2) {
errorLog(msg + lines[i]);
}
}
}
}
throw("Assertion failed with: " + msg);
};
errorLog = function(msg) {
if(typeof console.error == 'function') {
console.error(msg);
} else {
function errorLog(msg) {
console.log("foo");
setTimeout(function() {
throw new Error(msg);
}, 0);
}
}
};
}
/**
*将消息记录到控制台:
*或者使用jquery的console.error
*或者引发异常。
*
*调用initDevMode();使用前请先激活
*用于:
*断言(,“消息”);
*断言(1!=1,“啊哦!”);
*
*使用以下命令记录错误:
*错误日志(消息);
*例如:错误日志(xhr.状态);
*/
assert=函数(test,msg){}
errorLog=函数(msg){}
initDevMode=函数(){
断言=函数(测试,消息){
msg=msg | |“(无错误消息)”;
如果(!测试){
试一试{
抛出错误();
}捕获(e){
var foo=e;
var lines=e.stack.split('\n');
对于(i行){
如果(i>2){
错误日志(消息+行[i]);
}
}
}
}
抛出(“断言失败,错误为:“+msg”);
};
errorLog=函数(msg){
if(typeof console.error=='function'){
控制台错误(msg);
}否则{
函数错误日志(msg){
控制台日志(“foo”);
setTimeout(函数(){
抛出新错误(msg);
}, 0);
}
}
};
}
看看;基本上,它是一个可以从代码中删除几乎具有任意逻辑的断言的工具。它可以方便地用作批处理程序来生成生产代码,也可以用作fastcgi支持的脚本目录,您可以在需要测试代码性能/配置代码时使用它。无论出于何种原因,当console.assert不可用时,我都使用以下内容来替换它
这绝对不是一个事实上的标准,也远不理想,但它确实满足了您的要求,即不在生产模式中评估断言。此外,它还显示了触发失败断言的表达式,这有助于调试
扭曲的调用语法(带有函数表达式)用于创建闭包,以便assert函数可以访问其调用者可以访问的相同变量
我怀疑这有很高的编译时和运行时开销,但我没有尝试验证这一点
function assert(func) {
var name;
if (typeof(ENABLE_ASSERTIONS) !== "undefined" && !ENABLE_ASSERTIONS) {
return;
}
name = arguments.callee.caller;
name = name ? name.name : "(toplevel)";
if (!func()) {
throw name + ": assertion failed: " + ('' + func).replace(/function[^(]*\([^)]*\)[^{]*{[^r]*return/, '').replace(/;[ \t\n]*}[ \t\n]*$/, '');
}
}
使用它看起来像:
function testAssertSuccess() {
var i = 1;
assert(function() { return i === 1; });
}
function testAssertFailure() {
var j = 1;
assert(function() { return j === 2; });
}
ENABLE_ASSERTIONS = true;
testAssertSuccess();
testAssertFailure();
嗯 也许只是一个措词上的小毛病,但零性能是不好的。也许你的意思是接近零的开销。断言?嗯,
console.assert()
?@Marc B:你说得对:)正在修复它。@Šime Vidas:不确定该函数是否可以跨所有浏览器移植。同意!所以,没有办法使参数计算无效,对吗?唯一的办法是删除它,或者将断言语言更改为更像jUnit/JSUnit/QUnit,其中有不同的检查assertTrue、assertFalse、AssertQuals、assertNotSame。即将批准答案。如果可能的话,你能澄清一下后者吗?比如,如果我有assertTrue(a!=b)
-我可以应用什么技巧,这样a=b
不会在生产模式下进行计算(减少开销)?jUnit方式将是assertNotSame(“检查foo”,a,b)代码>并且比较是在函数中完成的,而不是在函数调用中完成的。“throw”(“Assertion failed”)“不应该驻留在“if(!test)”块中吗?