Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的断言_Javascript_Assert_Assertions - Fatal编程技术网

JavaScript中的断言

JavaScript中的断言,javascript,assert,assertions,Javascript,Assert,Assertions,广泛阅读JavaScript中的各种断言框架。是否存在任何事实上/最常见的“标准”库/框架?选择一个时,哪些点最值得注意 在生产模式下,我能想到的(唯一)要求是接近零的性能开销。两种可能的解决方案: 让构建发布脚本删除断言行 或 让构建脚本重写Assert函数,使它只是一个空函数。这样做的缺点是,如果断言调用中包含逻辑[aka assert(x>100,“foo”)],那么该逻辑[x>100]仍将运行 以下是我使用的: 在编写代码时,我有initDevMode();在我正在处理的文件的顶部,当我

广泛阅读JavaScript中的各种断言框架。是否存在任何事实上/最常见的“标准”库/框架?选择一个时,哪些点最值得注意


在生产模式下,我能想到的(唯一)要求是接近零的性能开销。

两种可能的解决方案:

让构建发布脚本删除断言行

让构建脚本重写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)”块中吗?