如何检测用javascript调用的函数

如何检测用javascript调用的函数,javascript,aop,Javascript,Aop,我有一个javascript函数 var myLibraryFunction = callItOnce(libraryFunction); myLibraryFunction(); // it runs myLibraryFunction(); // null libraryFunction(); // it runs 如何检查: 如果调用了函数(在部分中使用此函数),则不调用该函数 如果未调用函数(在部分中没有此函数),则调用该函数 与require\u once或include\u o

我有一个javascript函数

var myLibraryFunction = callItOnce(libraryFunction);
myLibraryFunction(); // it runs
myLibraryFunction(); // null
libraryFunction(); // it runs
如何检查:

  • 如果调用了函数(在
    部分中使用此函数),则不调用该函数

  • 如果未调用函数(在
    部分中没有此函数),则调用该函数


require\u once
include\u once
withPHP

类似,您可以在自定义命名空间中使用全局变量来存储函数是否已被调用

var called = false;
function blah() {
   called = true;
}

if ( !called ) {
   blah();
}
if(!window.mynamespace){
    window.mynamespace={};
}

mynamespace.callMeOnlyOnce=function(){

    if(mynamespace.alreadyCalled)return;

    alert('calling for the first time');
    mynamespace.alreadyCalled=true;
};

// alert box comes
mynamespace.callMeOnlyOnce();


// no alert box
mynamespace.callMeOnlyOnce();
使用装饰图案

// your function definition
function yourFunction() {}

// decorator
function callItOnce(fn) {
    var called = false;
    return function() {
        if (!called) {
            called = true;
            return fn();
        }
        return;
    }
}

yourFunction(); // it runs
yourFunction(); // it runs    
yourFunction = callItOnce(yourFunction);
yourFunction(); // it runs
yourFunction(); // null
此解决方案为实现目标提供了一种无副作用的方法。您不必修改原始函数。它甚至可以与库函数一起工作。可以为修饰函数指定新名称以保留原始函数

var myLibraryFunction = callItOnce(libraryFunction);
myLibraryFunction(); // it runs
myLibraryFunction(); // null
libraryFunction(); // it runs

静态变量

下面介绍如何使用自调用函数创建静态(如C)变量,将静态变量存储在闭包中

var myFun = (function() {
  var called = false;
  return function() {
    if (!called) {
      console.log("I've been called");
      called = true;
    }
  }
})()
将想法抽象出来

这里有一个函数,它返回一个只被调用一次的函数,这样我们就不必担心为每个函数添加锅炉板代码

var myLibraryFunction = callItOnce(libraryFunction);
myLibraryFunction(); // it runs
myLibraryFunction(); // null
libraryFunction(); // it runs
函数makeSingleCallFun(fun){
var=false;
返回函数(){
如果(!调用){
调用=真;
返回乐趣。应用(这个,参数);
}
}
}
var myFun=makeSingleCallFun(函数(){
log(“我被叫过”);
});
myFun();//有人打电话给我

myFun();//对那些全局变量nazis不执行任何操作[因为它在全局范围内],可以使用blah.called而不是var blah。。。假设blah已经定义。不过,这段代码对我来说已经足够了。这种模式的缺点是,无论函数调用在哪里被调用,都必须将其包装在条件语句中。@ItzWarty正如Török Gábor指出的那样,这对我来说还不够。全球人不好是有原因的,所以我像躲避瘟疫一样躲避他们,叫我全球纳粹!这里的许多其他示例不使用全局变量,也不需要在调用的任何地方都使用条件来包装调用
值指的是全局对象,而不是函数本身,
allreadyCalled
最终将成为全局对象的一个属性。这是因为函数是从没有基对象的引用调用的:
callMeOnlyOnce()。在所有答案中,这是一个需要重复代码最多的答案。每次通话都需要设置标志,并用条件包装。这很有效,谢谢接听。“我被困了2个多月,而你帮助了我,你的代码就像一个符咒一样有效。”胡安·门德斯重复代码?这是个问题吗?使用函数名作为参数生成包装函数。我在这里只描述了一个想法。哦,不,我跳过了你的答案,添加了一个几乎相同的答案。我会留下我的答案,因为我也展示了一种不同的方式。然而,这是怎样的装饰图案?我认为这更像是面向方面的编程。@胡安你们都是对的,AOP经常使用decorator模式,也被称为函数组合,可能是@SeanPatrickFloyd的重复。一开始我以为
callee
是关于
调用的
函数名的拼写错误,但它是一个变量,并且确实匹配,所以我真的不知道为什么被否决了。你在评论之前试过代码吗?@erm3nda不知道。这是4年前的事了