Javascript 检查函数是否接受数组或单值输入
我正在尝试编写一个函数,它接受一个数组和另一个函数作为输入。关于提供的函数,我只知道它Javascript 检查函数是否接受数组或单值输入,javascript,Javascript,我正在尝试编写一个函数,它接受一个数组和另一个函数作为输入。关于提供的函数,我只知道它 接受单个数字参数并返回新的数字或 获取一个数字数组并返回一个新的数字数组 在我的函数中,我想检查这是第一种还是第二种情况,以确定是否使用Array.prototype.map()调用提供的函数 所以有了这两个函数 var unknownFunction = function( unknownInput ) { //Does stuff with input //returns number or a
Array.prototype.map()
调用提供的函数
所以有了这两个函数
var unknownFunction = function( unknownInput ) {
//Does stuff with input
//returns number or array of numbers...
return someValueOrValues
}
及
有没有办法深入第一个函数,找出调用它的最佳方法 由于JavaScript是一种动态类型化语言,函数的输入参数一旦有人使用某个参数调用它就具有类型 一种优雅且可行的方法是向整个给定函数添加一个属性,以提示输入参数类型:
var func = function() {};
func.type = "number"; // a function decorator
var mainFunction = function(anArray, inputFunc) {
if(typeof inputFunc != "function") {
throw Error("Please supply a function as 'inputFunc'!");
}
switch(inputFunc.type) {
case "number":
return anArray.map(preFunction);
case "array":
return preFunction(anArray);
default:
throw Error("Type not supported");
}
};
mainFunction([1,2,3], func);
当您使用动态类型语言时,您需要考虑使用和/或使用进行编码。由强类型语言提供的类型安全性被良好的文档所取代
例如:
提供一个函数作为第二个参数,并带有一个类型
属性
main函数
谓词的预期类型是什么
功能
我会使用try-catch方法,但会测试实际的函数,如果其中一个函数未能尝试下一个函数 假设这些是作为未知函数传入的函数。他们每个人只修改一个数字,将其加上1
function onlyTakesNumber(num) {
return num + 1;
}
function onlyTakesArray(arr) {
return arr.map(num => num + 1);
}
现在,这是您的主要功能。在try
中添加映射的原因是为了测试,确保在将数组传递给onlyTakesNumber
函数时没有返回字符串。额外的测试映射将再次显示代码是否需要跳入捕获
var mainFunction = function (anArray, preFunction) {
try {
// the map on the end checks to make sure you did not get a string back
anArray = preFunction(anArray).map(test => test);
}
catch (e) {
anArray = anArray.map(preFunction);
}
// Do whatever else with anArray
return anArray;
};
console.log(mainFunction([1, 2, 3], onlyTakesArray)); // [2, 3, 4]
console.log(mainFunction([7, 8, 9], onlyTakesNumber)); // [8, 9, 10]
这里有一个测试,你可以在上面测试一下。最简短的回答是:“你不能” 你可以试试看。当数组只是一个数字时,尝试访问它会导致错误…这是不可能的。通常,如果不运行函数,就无法判断函数是否接受数组或数字,即使这样,也无法确定。这是的子类,没有解决方案。@meagar是对的,但您可以使用Function.prototype.toString,在大多数浏览器中返回函数源代码+参数名的一些约定,例如,如果第一个参数名为array,则可能会返回work@meagar考虑<代码>函数未知函数(未知输入){if(Math.random()>0.5){将unknownInput视为一个数字}或者{将unknownInput视为一个数组}。此函数每次调用时都会改变其行为!这比停止问题更糟糕,因为即使对于相同的输入行为也会改变!@RaymondChen是的,我非常清楚。这不是“更糟”与停顿问题相比,这是同一个问题。我明确地说“即使那样,你也不能确定”为了解决这个问题,我们举了一个典型的例子,说明为什么停止问题很难解决。这个例子使用了您的确切逻辑,简单地用
返回/不返回
代替像对待数字一样对待
/像对待数组一样对待
。最简短的注释是“为什么?”。你不能!任何外部函数都不能访问另一个函数的参数,除非你硬编码返回它们。@ocanal,每一个昨天的JavaScript新手都知道——询问是否有某种黑客行为——是不被禁止的——但答案永远是:不,你不能——这是因为你不被允许——这是一个安全问题很高兴知道为什么我投了反对票,知道我的方法是否被打破了……马蒂亚斯,不幸的是@kevbot的观察(另一个答案)是准确的--我无法访问函数来决定是否添加类型属性。不过,我认为这是一个非常巧妙的解决方案,如果try/catch解决方案导致问题,我可能会尝试找到一种方法使此方法起作用。谢谢!@SteveLadavich正如我在评论中对另一位回答者所说的那样,您不必担心允许访问函数以向函数对象添加类型属性。只是定义这些函数的人应该添加整个属性。在AngularJS中,此模式用于定义显式注入:controller.$inject=[“$scope”]
,这是现在装饰器的常见模式。@SteveLadavich这取决于您是否采用“尝试-捕获”路线。顺便说一句,正如我所说的,这是一种反模式,是解决您的问题的最简单但最糟糕的解决方案…@SteveLadavich顺便说一句,如果您甚至无法访问函数的源代码,这不是您在问题中说过的,也不是对于那些有权访问整个源代码库的人来说,我的答案会很好用,而且因为StackOverflow答案不仅仅是给OP(你)的,所以把我的答案留给未来的访问者(或者甚至是你,如果你可以用这种方法的话)没有什么错!:)可怕的解决方案。这就是所谓的反模式@MatíasFidemraizer,您的答案甚至没有解决实际问题OP“关于提供的函数,我只知道它是……”。他无权使用函数来决定是否执行此操作:func.type=“number”代码>,答案取决于此。您不需要访问该函数就可以向函数对象添加属性。正确,但他不知道要向属性添加什么值,因为他无法读取函数来知道它应该接受什么、数字或数组。顺便说一句,我的答案解决了实际问题。你的也是。您的问题是,它对性能有很大影响,而且是一种非常糟糕的编码实践。这不是“你的对我的”。。。当我在你的回答中添加评论时,我独立于我的回答:这是一个糟糕的解决方案。
var mainFunction = function (anArray, preFunction) {
try {
// the map on the end checks to make sure you did not get a string back
anArray = preFunction(anArray).map(test => test);
}
catch (e) {
anArray = anArray.map(preFunction);
}
// Do whatever else with anArray
return anArray;
};
console.log(mainFunction([1, 2, 3], onlyTakesArray)); // [2, 3, 4]
console.log(mainFunction([7, 8, 9], onlyTakesNumber)); // [8, 9, 10]