javascript - How do I refer to arguments of a function when the function is passed in as a parameter?
问题描述
New to JavaScript, so give me some leeway.
I'm currently trying to simulate contracts in JavaScript. There are preconditions and postconditions which can be defined when you declare a function. I've compiled a simple setup of how it should work below.
Function mult() has a few contracts which should check if the two inputs are numbers and should check if the resulting output is also a number.
//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();
I'm fairly sure a lot of the contract(){} function is wrong and after a lot of trial and error I have ended up here.
Currently I'm trying to loop through all the preconditions and call them with the arguments of f. From my understanding, (arguments) refers to the arguments of the current function, but I'm looking for the arguments of f, not of contract. f.arguments
I've also tried to do this with JavaScript proxies which can intercept function calls by setting traps for apply and construct but have gotten stuck as well.
Any help and pointers would be greatly appreciated. Using node.js to run this program.
解决方案
你可以尝试这样的事情:
"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
}
推荐阅读
- python - 将 for 循环更改为 .apply() 期间发生错误
- reactjs - React 中的 MUI RadioGroup 设置
- reactjs - 空输入提交时显示值类型错误消息而不是必需的错误消息
- linux - Readline 不读取在 INPUTRC 变量中指定的用户配置
- mongodb - Mongoose 没有自动增加 __v
- javascript - 无法在 React 组件中接收和显示道具
- flutter - 是否可以在 Flutter 中更改所选标签栏图标的大小?
- assembly - NASM:在我的打印功能中出现分段错误
- javascript - Splay Tree 实现:搜索功能 - Zag zag 旋转错误
- json - 将表示 JSON 的字符串切片转换为 JSON 并响应请求