当函数作为参数传入时,如何引用函数的参数?

时间:2018-07-18 02:39:59

标签: javascript

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运行该程序。

2 个答案:

答案 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;
    }
}