JavaScript新手,请给我一些余地。
我目前正在尝试使用JavaScript模拟合同。声明函数时,可以定义前提条件和后置条件。我已经在下面对它的工作方式进行了简单的设置。
函数mult()有一些协定,应检查两个输入是否为数字,并应检查结果输出是否也为数字。
//CONTRACT
function isNumber(v) {
return !Number.isNaN(v) && typeof v === 'number';
}
isNumber.expected = "number";
/**
* @param preList Array of contracts to check
* @param post Expected result type as a contract
* @param f the function
*/
function contract (preList, post, f) {
//??? No idea
//precondition
for (let i = 0; i < preList.length; i++) { //THIS DOESNT WORK
let valid = preList[i].call(this, f.arguments[i]);
if (valid === false) throw "caller's fault";
}
//postcondition
let result = f.call(this, f.arguments);
if ((post.call(this, result)) === false) throw "library's fault";
}
//EXAMPLE
var mult = contract(
[isNumber, isNumber],
isNumber,
function mult (x, y) {
return x*y;
});
//TEST CODE
console.log("First test")
console.log(mult(3, 4));
console.log();
console.log("Second test")
try {
console.log(mult(3, "four"));
} catch (e) {
console.log(e.message);
}
console.log();
我相当确定很多contract(){}函数是错误的,经过大量的试验和错误,我到这里为止。
当前,我正在尝试遍历所有前提条件,并使用f的参数进行调用。根据我的理解,(自变量)是指当前函数的自变量,但是我正在寻找f的自变量,而不是合同的自变量。 f。参数
我还尝试使用JavaScript代理来做到这一点,这些代理可以通过设置Apply和Construct陷阱来拦截函数调用,但是也被卡住了。
任何帮助和指针将不胜感激。使用node.js运行该程序。
答案 0 :(得分:2)
您可以尝试以下操作:
"use strict";
function isNumber(v) {
return !Number.isNaN(v) && typeof v === "number";
}
/**
* @param preList Array of contracts to check
* @param post Expected result type as a contract
* @param f the function
* @param array: arguments passed to function f
*/
function contract(preList, post, f, args) {
for (let i = 0; i < preList.length; i++) {
let valid = preList[i].call(this, args[i]);
if (valid === false) throw "caller's fault";
}
let result = f.apply(this, args);
if (post.call(this, result) === false) throw "library's fault";
return result;
}
let mult = function(x, y) {
let f = function(x, y) {
return x * y;
};
return contract([isNumber, isNumber], isNumber, f, arguments);
};
console.log("First test");
console.log(mult(3, 4)); // 12
console.log("Second test");
try {
console.log(mult(3, "four"));
} catch (e) {
console.log(e); // caller's fault
}
答案 1 :(得分:1)
现在到期日期已经过去,这是我的解决方案。我不应该直接返回一个值,而是一个在检查输入参数和输出后将返回值的函数。
function contract (preList, post, f) {
return function() {
for (let i = 0; i < preList.length; i++) {
let valid = preList[i].call(this, arguments[i]);
if (!valid)
throw new Error("Contract violation in position " + i + ". Expected " + preList[i].expected + " but received " + arguments[i] + ". Blame -> Top-level code");
}
let result = f.apply(this, arguments);
if (!post(result))
throw new Error("Contract violation. Expected " + post.expected + " but returned " + result + ". Blame -> " + f.name);
return result;
}
}