在JavaScript中,是否有可能在整个程序的整个执行过程中测试条件是否仍然正确?在这里,我想确保变量a总是可以被整除3,从程序的开始到结束。
//Assert that the following is always true, and print an error message if not true
ensureAlwaysTrue(a % 3 == 0); //print an error message if a is not divisible by 0
//from this point onward
a = 6;
a = 10 //print error message, since a % 3 != 0
function ensureAlwaysTrue(){
//this is the function that I'm trying to implement.
}
一个解决方案是添加语句来检查每个变量赋值后的断言,但这将是多余和繁琐的。有没有更简洁的方法来检查一个条件在整个程序的执行过程中是否为真?
答案 0 :(得分:3)
function Model(value){
this.value = value;
}
Model.prototype = {
get: function(){
return this.value;
},
set: function(value){
if(this.validate(value)){
this.value = value;
return this;
}
throw Error('Not a valid value.');
},
test: function(func){
this.validate = func;
return this;
}
};
var a = new Model();
a.test(function(val){ return val == 7 });
// Sets value of a to 7
a.set(7);
// Gets value of a (7 in this case)
a.get();
// Throws an error
a.set(5);
答案 1 :(得分:2)
没有。
你可以在Javascript中找到最接近的工具,就是找到一些“编译”你的代码的工具,在每个语句之后自动注入ensure
函数调用,比如AspectJ for Java。
使用其他语言进行此操作的潜在方法可能是使用后台线程; Javascript线程(Web worker)将无法访问其他线程中的变量。 Javascript也是一种只按顺序运行代码的解释语言 - 除非ensure
函数实际存在于执行路径中,否则它将不会执行。
答案 2 :(得分:1)
好吧,你可以添加一个定时间隔,比如
assertInterval = 10; //milisseconds
function ensureAlwaysTrue(condition)
{
setInterval(function(){ if(!condition()) error(); }, assertInterval);
}
你会这样称呼:
var a = 6;
ensureAlwaysTrue(function(){return (a % 3 == 0);});
那会抓住它,但最多延迟assertInterval
毫秒。
修改强> 它实际上是行不通的,因为@Chris指出:“你的间隔函数实际上不会在当前执行函数的语句之间运行”。 这是真的,它只适用于在事件之间断言等。
答案 3 :(得分:0)
基于@Chris(http://stackoverflow.com/a/14534019/1394841)的想法,您可以将整个代码括在一个字符串中,然后执行以下操作:
function ensureAlwaysTrue(condition, code)
{
var statements = code.split(";");
for (var i = 0; i < statements.length-1; i++) { //last statement is empty
eval(statements[i] + ";");
if (!condition()) error();
//break; //if desired
}
}
var code =
"a = 6;\
a = 10; //print error message, since a % 3 != 0\
";
ensureAlwaysTrue(function(){return (a % 3 == 0);}, code);