1

我想知道最好的方法是检查一个参数是否已经在函数中被调用。

我想做的 Sudo 代码:

function returnArg(arg){
 if(argHasbeenCalled){
   return "foo";
  }   
  else{
    return arg;
  }
}

我的解决方案是:

var myArray = [];
function returnFoo(arg){

    if(jQuery.inArray(arg, myArray) < 1){
        return "Foo";
    }   
    else {
        return "bar";
    }
    newArray.push(arg);
}
4

3 回答 3

2

一个简单的解决方案是:

// generic helper function
function rememberCalls(fn) {
  var calledArgs = {};
  return function(arg) {
    if (!(arg in calledArgs)) {
      calledArgs[arg] = fn(arg);
    }
    return calledArgs[arg];
  }
}

// example
var addQuestionMark = rememberCalls(function(str) {
  return str + '?';
});

addQuestionMark('What is your name'); // the function will be called
addQuestionMark('What is your name'); // the function will be skipped
于 2013-10-19T17:01:37.950 回答
2

您的代码将在将参数存储在数组中之前返回。

除非您点击 else 分支,否则您不需要将参数存储在数组中。所以考虑这样的事情:

var myArray = [];
function returnFoo(arg)
{
  if (jQuery.inArray(arg, myArray) === -1)
  {
    return "Foo";
  }   
  else
  {
    myArray.push(arg);
    return "bar";
  }
}
于 2013-10-19T16:37:31.087 回答
1

我认为您想要的称为memoization。如果您只想知道参数是否被处理过,这与您对结果不感兴趣并不完全相同,但您可以使用类似的方法。

var myFn = (function (processedArgs) {
    return function (arg) {
        if (processedArgs[arg]) {
            console.log('already processed');
            //do something
            return;
        }

        console.log('not processed');
        //do something
        processedArgs[arg] = true;
    };
})({});

myFn(1); //not processed
myFn(1); //already processed

但是,如果arg是一个对象,您将不得不使用该对象的某些属性使其唯一生成密钥。如果这不可能,您可以将它们存储在数组中,而不是将对象用作映射并用于array.indexOf(arg)查看对象是否在数组中。

您也可以使用ObjectMap. 不幸的是,浏览器仍然不支持Map,但之前链接的答案将向您展示如何自己实现一个。

于 2013-10-19T16:36:27.743 回答