2010-07-26 7 views
11

iwie eine Funktion zu erkennen, wurde mit Javascript

eine JavaScript-Funktion namens

wie überprüfen

, wenn die Funktion aufgerufen wurde (in <head></head> Abschnitt haben diese Funktion), dann rufen Sie nicht Funktion

wenn Funktion wurde nicht (in <head></head> Abschnitt haben diese Funktion nicht), dann rufen Sie Funktion

wie require_once oder include_once mit php

genannt

mir helfen danken

+0

möglich Duplikat [Wie Sie die CLIP-Funktion in JavaScript herauszufinden tun?] (Http://stackoverflow.com/questions/280389/how-do-you-find-out-the-caller-function -in-javascript) – Ralgha

Antwort

24

zwei Optionen:

Statische Variablen Hier ist, wie statisch zu schaffen (wie in C) Variablen selbst Funktionen aufrufen mit Ihrer statischen Variablen in einem Verschluss zu speichern.

var myFun = (function() { 
    var called = false; 
    return function() { 
    if (!called) { 
     console.log("I've been called"); 
     called = true; 
    } 
    } 
})() 

Leer Funktion Ersatz die Funktion auf eine leere Funktion gesetzt, nachdem es ausgeführt wird.

function callonce() { 
    console.log("I've been called"); 
    arguments.callee = function() {}; 
} 

Zusammenfassung der Idee Hier ist eine Funktion, die eine Funktion gibt, die nur einmal aufgerufen wird, so müssen wir über das Hinzufügen zu jeder Funktion Kesselblech Code keine Sorge.

function makeSingleCallFun(fun) { 
    var called = false; 
    return function() { 
    if (!called) { 
     called = true; 
     return fun.apply(this, arguments); 
    } 
    } 
} 

// Alternate implementation 
function makeSingleCallFun(fun) { 
    return function() { 
     return fun.apply(this, arguments); 
     arguments.callee = function() {}; 
    } 
} 

var myFun = makeSingleCallFun(function() { 
    console.log("I've been called"); 
}); 
myFun(); // logs I've been called 
myFun(); // Does nothing 
+0

Wer hat das abgelehnt? +1 zu balancieren –

+0

@SeanPatrickFloyd Am Anfang dachte ich, dass 'callee' ein Tippfehler über 'genannt'Funktionsname war, aber es ist eine Variable und stimmt überein, so dass ich nicht wirklich weiß, warum runtergeregelt wurde. Hast du den Code vor dem Kommentieren getestet? – erm3nda

+3

@ erm3nda keine Ahnung. Das ist vor 4 Jahren –

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

if (!called) { 
    blah(); 
} 
+1

Für diese global-variable-nazis [da dies im globalen Gültigkeitsbereich ist] kannst du blah.called anstelle von var blah ... verwenden, vorausgesetzt, blah ist bereits definiert. Dieser Code ist ziemlich hübsch für mich. – Warty

+0

Der Nachteil dieses Musters besteht darin, dass Sie den Funktionsaufruf überall dort, wo er aufgerufen wird, in eine bedingte Anweisung einfügen müssen. –

+0

@ItzWarty Das ist nicht schön genug für mich, wie Török Gábor betonte.Es gibt einen Grund, warum Globals schlecht sind, also vermeide ich sie wie die Pest, nenn mich einen Global-Nazi! Viele weitere Beispiele hier, die keine globale Variable verwenden und nicht erfordern, dass der Aufruf mit einer Bedingung überall umschlossen wird, heißt es –

4

, die leicht zu erreichen ist, wie JavaScript-Funktionen Objekte sind, die Mitglieder und Eigenschaften haben:

var callMeOnlyOnce=function(){ 

    if(this.alreadyCalled)return; 

    alert('calling for the first time'); 

    this.alreadyCalled=true; 
}; 

// alert box comes 
callMeOnlyOnce(); 


// no alert box 
callMeOnlyOnce(); 

EDIT: richtig

Wie wies darauf hin, Durch CMS ist das nicht so einfach. Hier ist eine überarbeitete Version, die stattdessen einen benutzerdefinierten Namespace verwendet.

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(); 
+1

Der 'this'-Wert bezieht sich auf das globale Objekt, nicht auf die Funktion selbst, und 'allreadyCalled' wird am Ende eine Eigenschaft des globalen Objekts sein. Dies liegt daran, dass die Funktion von einer Referenz aufgerufen wurde, die kein Basisobjekt hat: 'callMeOnlyOnce();'. [Weitere Informationen über 'this'] (http://stackoverflow.com/questions/3320677/this-operator-in-javascript/3320706#3320706) – CMS

10

Dekorationsmuster verwenden.

// 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 

Diese Lösung bietet einen nebenwirkungsfreien Weg, um Ihr Ziel zu erreichen. Sie müssen Ihre ursprüngliche Funktion nicht ändern. Es funktioniert sogar mit Bibliotheksfunktionen. Sie können der dekorierten Funktion einen neuen Namen zuweisen, um die ursprüngliche Funktion beizubehalten.

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

Oh nein, ich überspringe deine Antwort und fügte eine Antwort hinzu, die fast die ist gleich. Ich werde meine Antwort verlassen, da ich auch einen anderen Weg gezeigt habe. Wie aber ist das das Dekorationsmuster? Ich denke, das ist mehr wie aspektorientierte Programmierung. –

+0

@Juan Sie sind beide richtig, AOP verwendet oft das Dekoratormuster –

0
If (!your_func.called) { 
    your_func.called = true; 
    your_func(); 
} 
+0

Von allen Antworten, das ist die, die die meisten Code-Wiederholung erfordert. Jeder Aufruf muss das Flag setzen und mit einem Conditional umbrechen. –

Verwandte Themen